2017-06-12 20 views
2

Ich möchte Bytes in meine PostgreSQL (9.5.7) Datenbankspalte mit dem Typ bytea einfügen, mit dem Psycopg2 (2.7.1) copy_from() Methode.PostgreSQL - Psycopg2 - copy_from - Ungültige Bytefolge für die Codierung "UTF8": 0x00

Ich kann mein Bytes mit dem folgenden Code ein:

psycopg2_cursor.copy_from(
    StringIO("\x30\x40\x50"), 
    "my_table", 
) 

durch Ausführen eine SELECT in meinen Tisch nach dem Einsetzen, erhalte ich den erwarteten Wert von der bytea Spalte:

\x304050

Jetzt möchte ich meine Bytes mit dem Byte 0:

psycopg2_cursor.copy_from(
    StringIO("\x00\x30\x40\x50"), 
    "my_table", 
) 
voranstellen

Ich erhalte den Fehler: psycopg2.DataError: Ungültige Byte-Sequenz für die Codierung "UTF-8": 0x00. Aus meiner Sicht sollte dieser Fehler nur beim Einfügen eines Null-Bytes in ein Textfeld ausgelöst werden, sollte aber wie erwartet in einem Bytea-Feld funktionieren. Fehle ich etwas? Gibt es eine einfache Möglichkeit, ein Null-Byte in eine Bytea-Spalte einzufügen?

Danke!

+0

was ist Ihr 'standard_conforming_strings' Einstellung? –

+0

hast du 'StringIO ('\ x30 \ x40 \ x50')' stattdessen? .. –

Antwort

0

https://www.postgresql.org/docs/current/static/sql-copy.html

the following characters must be preceded by a backslash if they appear as part of a column value: backslash itself, newline, carriage return, and the current delimiter character.

nur realisiert werden Sie COPY verwenden, so dass Sie Backslash haben zu entkommen:

t=# copy b from stdin; 
Enter data to be copied followed by a newline. 
End with a backslash and a period on a line by itself. 
>> \\x00 
>> \. 
COPY 1 
t=# copy b from stdin; 
Enter data to be copied followed by a newline. 
End with a backslash and a period on a line by itself. 
>> \x00 
>> \. 
ERROR: invalid byte sequence for encoding "UTF8": 0x00 
CONTEXT: COPY b, line 1: "\x00" 

dies den Trick tun sollten:

psycopg2_cursor.copy_from(
    StringIO("\\x00\\x30\\x40\\x50"), 
    "my_table", 
) 
+0

Ich habe den folgenden Parameter zu meiner psycopg2-Verbindung hinzugefügt: 'options =" ​​- c standard_conforming_strings = on "', aber ich bekomme immer noch dasselbe Error. Ich habe versucht, 'StringIO ('\ x30 \ x40 \ x50')' und es funktioniert richtig, aber ich muss wirklich dieses Null-Byte einfügen. Ich habe versucht, statt eines StringIO ein ByteIO zu verwenden, aber ich bekomme immer noch das gleiche Ergebnis. – jean553

+0

versuchen Sie das? 'select decode ('00203040', 'hex')' - erzeugt es dein gewünschtes Ergebnis? .. –

+0

Ja, es erzeugt das gewünschte Ergebnis, wenn es in PSQL verwendet wird ('INSERT INTO my_table VALUES (decode ('001060', ' hex ')); '), aber ich muss meine Bytes mit der copy_from() -Methode aus meinem Python-Code einfügen, nicht direkt mit einer SQL-Abfrage. – jean553

0

ein binäres einzufügen mit copy ist es notwendig, diezu verwendenwas ist nicht was du willst. Verwenden Sie die extras.execute_values method

from psycopg2.extensions import Binary 

binaries = [[Binary('\x00\x20')], [Binary('\x00\x30')]] 

insert_query = 'insert into t (b) values %s' 
psycopg2.extras.execute_values (
    cursor, insert_query, binaries, page_size=100 
) 
Verwandte Themen