好的,我找到了答案。在 PostgreSQL 中,您可以使用 Python 编写函数。为了启用 Python 的使用,您必须安装 PostgreSQL 安装所需的特定 Python 版本,并使其在 PATH 环境变量中可用。您可以通过查看安装说明找到安装 PostgreSQL 所需的 Python 版本。我目前在 Windows 上使用 PostgreSQL 9.6.5,它需要 Python 3.3。我最初尝试了最新的 Python 3.6,但它不起作用。我选择了最新的适用于 Windows 的 Python 3.3,即 3.3.5。
CREATE EXTENSION plpython3u;
安装 Python 后,您可以通过在您的数据库上执行它在 PostgreSQL 中启用它,如此处记录的https://www.postgresql.org/docs/current/static/plpython.html。从那里,您可以使用 Python 主体编写任何函数。
对于我的具体情况来回转换bytea
,double precision[]
我编写了以下函数:
CREATE FUNCTION bytea_to_double_array(b bytea)
RETURNS double precision[]
LANGUAGE 'plpython3u'
AS $BODY$
if 'struct' in GD:
struct = GD['struct']
else:
import struct
GD['struct'] = struct
return struct.unpack('<' + str(int(len(b) / 8)) + 'd', b)
$BODY$;
CREATE FUNCTION double_array_to_bytea(dblarray double precision[])
RETURNS bytea
LANGUAGE 'plpython3u'
AS $BODY$
if 'struct' in GD:
struct = GD['struct']
else:
import struct
GD['struct'] = struct
# dblarray here is really a list.
# PostgreSQL passes SQL arrays as Python lists
return struct.pack('<' + str(int(len(dblarray))) + 'd', *dblarray)
$BODY$;
在我的例子中,所有的双打都存储在小端,所以我使用<
. 我还将struct
模块的导入缓存在全局字典中,如https://stackoverflow.com/a/15025425/5274457中所述。我使用 GD 而不是 SD,因为我希望可以在我可能编写的其他函数中使用导入。有关 GD 和 SD 的信息,请参阅https://www.postgresql.org/docs/current/static/plpython-sharing.html。
知道我的数据库中的 blob 存储为小端序时,要查看它的实际效果,
SELECT bytea_to_double_array(decode('efbeaddeefbeadde', 'hex')), encode(double_array_to_bytea(array[-1.1885959257070704E148]), 'hex');
我得到的答案是
bytea_to_double_array | encode
double precision[] | text
-------------------------+------------------
{-1.18859592570707e+148} | efbeaddeefbeadde
'efbeaddeefbeadde'
小端在哪里'deadbeefdeadbeef'
。