4

我目前正在尝试在 PL/Python 中编写一个过程来执行一些数据的转换,然后将结果作为bytea. (实际上,这很丑:在 OCaml 中编组数据!在 Python 和 OCaml 中同时出现丑陋;我应该获得奖牌吗?)

这是它的样子:

CREATE OR REPLACE FUNCTION ml_marshal(data varchar) RETURNS bytea as $$
    import tempfile, os

    fn = tempfile.mktemp()
    f = open(fn, 'w')

    dest_fn = tempfile.mktemp()

    f.write("let outch = open_out_bin \"" + dest_fn + "\" in " +
            "Marshal.to_channel outch (" + data + ") [Marshal.No_sharing]; " +
            "close_out outch")
    f.close()

    os.system("ocaml " + fn)
    os.unlink(fn)

    f = open(dest_fn, 'r')
    res = f.read()
    f.close()

    os.unlink(dest_fn)

    return res
$$ LANGUAGE plpythonu;

简而言之,它将一个小的 OCaml 程序写入一个临时文件,该临时文件创建另一个包含我们想要的数据的临时文件。然后我们读入那个临时文件,销毁它们,然后返回结果。

只是它不太有效:

meidi=# select * from tblmodel;
 modelid |      polies      
---------+------------------
       1 | \204\225\246\276
       2 | \204\225\246\276

每个有四个字节(应该有〜130)。如果我停止它取消链接文件,那么原因就很明显了;有四个非 NUL 字节,后跟几个 NUL,并且在从 Python 到 Postgres 的转换过程中,这些 NUL 似乎在某个阶段被视为终止符!

有谁知道为什么会发生这种情况,或者如何阻止它?文档没有启发性。

谢谢!

编辑:我发现其他人有同样的问题,但解决方案相当不令人满意。

4

2 回答 2

4

这已在 9.0 版中得到修复。我有同样的问题,所以我升级了。从发行说明

Improve bytea support in PL/Python (Caleb Welton)

Bytea values passed into PL/Python are now represented as binary, rather than the PostgreSQL bytea text format. Bytea values containing null bytes are now also output properly from PL/Python. Passing of boolean, integer, and float values was also improved.

我认为在以前的 PostgreSQL 版本中没有一个非常优雅的解决方案来解决这个问题。

于 2011-01-26T07:17:50.653 回答
1

您可以应用另一个 bodge-将 python 的返回值编码为 base64,并使用 PostgreSQL 的 decode 函数对其进行解码,即。decode(ml_marshal(xxx), 'base64').

或者按照 Adrian 的指示升级到 9.0 :)

于 2011-01-26T11:04:52.923 回答