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

それぞれに4バイトあります(約130バイトあるはずです)。ファイルのリンクを解除するのをやめると、その理由が明らかになります。非NULバイトが4つあり、その後に2つのNULが続きます。これらのNULは、PythonからPostgresへの変換によって、ある段階でターミネータとして扱われるようです。

なぜこれが起こるのか、それを止める方法を誰かが知っていますか?ドキュメントは啓発的ではありません。

ありがとう!

編集:私は同じ問題を抱えている他の誰かを見つけましたが、解決策はかなり不十分です。

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(ml_marshal(xxx), 'base64')

または、エイドリアンが示すように9.0にアップグレードします:)

于 2011-01-26T11:04:52.923 に答える