Comment puis-je retourner une chaîne binaire (bytea) dans une routine PL / Python PostgreSQL?

StackOverflow https://stackoverflow.com/questions/4801431

Question

Je suis actuellement en train d'écrire une procédure en PL / Python pour effectuer une conversion de certaines données, puis retourner le résultat en tant que bytea. (Il est assez moche, en fait:? Marshalling les données OCaml truand en Python et OCaml à la fois, dois-je obtenir une médaille)

Voici à quoi il ressemble:

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;

En bref, il écrit un petit programme OCaml à un tempfile qui crée une autre tempfile avec les données que nous voulons. On lit alors que tempfile dans Extermine les deux, et de retourner le résultat.

Seulement il ne pas tout à fait le travail:

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

Il y a quatre octets dans chacune (il devrait y avoir ~ 130). Si je l'arrête dissociant les fichiers, il devient évident pourquoi; il y a quatre non NUL octets, suivi par un couple de NUL, et il semble ces NUL sont traités comme terminateurs à un certain moment par la conversion de Python à Postgres!

Quelqu'un sait pourquoi cela se produit, ou comment l'arrêter? Docs ne sont pas éclairantes.

Merci!

Modifier : J'ai trouvé quelqu'un d'autre avec le même problème , mais la solution est assez peu satisfaisante.

Autres conseils

Vous pourriez appliquer un autre encode bodge- la valeur de retour de python en base64, et utiliser la fonction de décodage de PostgreSQL pour le décoder, à savoir. decode(ml_marshal(xxx), 'base64').

ou mise à jour 9.0 comme indiqué par Adrian:)

scroll top