2011-01-26 2 views
4

저는 현재 PL/Python에서 프로 시저를 작성하여 일부 데이터의 변환을 수행하고 결과를 bytea으로 리턴하려고합니다. (실제로, 아주 추한 : OCaml로의 데이터를 마샬링 한 번에 파이썬과 OCaml의에서 미운, 나는 메달을 얻어야한다!?)PL/Python PostgreSQL 루틴에서 바이너리 문자열 (bytea)을 반환하려면 어떻게해야합니까?

여기

는 것 같습니다 무엇 : 한마디로

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이 있어야한다). 파일 연결 해제를 중지하면 이유가 분명해집니다. 4 개의 non-NUL 바이트와 2 개의 NUL이 있으며, 파이썬에서 포스트그레스로의 변환에 의해 NUL이 어떤 단계에서 터미네이터로 취급됩니다!

왜 이런 일이 발생했는지 또는 어떻게 멈추는 지 아는 사람이 있습니까? 문서는 깨닫지 못합니다.

감사합니다.

: someone else with the same problem을 찾았지만 그 해결책은 상당히 만족스럽지 않습니다.

답변

4

릴리스 9.0으로 수정되었습니다. 나는 동일한 문제를 가지고 있었기 때문에 나는 업그레이드했다. release notes에서 :

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 버전에서이 문제에 대한 아주 우아한 해결책이 있다고 생각하지 않습니다.

+0

너무 쉽습니다. ;-) 포인터 주셔서 감사합니다! – Ashe

1

python의 반환 값을 base64로 적용하고 PostgreSQL의 디코드 함수를 사용하여 디코딩 할 수 있습니다. decode(ml_marshal(xxx), 'base64').

또는 Adrian에 의해 표시된대로 9.0으로 업그레이드하십시오.

+0

나쁘지 않습니다! 참으로 교묘하지만, 그럼에도 불구하고 포함되어 있습니다. – Ashe