PostgreSQL - Psycopg2 - copy_from - 用于编码的无效字节序列" UTF8":0x00

时间:2017-06-12 07:25:58

标签: python postgresql psycopg2

我想使用Psycopg2(2.7.1)copy_from()方法将字节插入到类型为bytea的PostgreSQL(9.5.7)数据库列中。

我可以使用以下代码插入我的字节:

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

通过在插入后执行SELECT到我的表中,我从bytea列中获得了期望值:

\x304050

现在,我想在字节0前加上我的字节:

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

我收到错误:psycopg2.DataError:编码的无效字节序列" UTF-8":0x00。根据我的理解,只有在将空字节插入文本字段时才会触发此错误,但应该按预期工作到bytea字段中。我错过了什么吗?有没有简单的方法将空字节插入bytea列?

谢谢!

2 个答案:

答案 0 :(得分:1)

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

  

如果以下字符必须以反斜杠开头   作为列值的一部分出现:反斜杠本身,换行符,运输   return,以及当前的分隔符。

刚刚意识到你正在使用COPY,所以你必须逃避反斜杠:

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"

这应该可以解决问题:

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

答案 1 :(得分:1)

要使用copy插入二进制文件,必须使用不是您想要的binary format。使用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
)