将json导入Postgres时的编码问题

时间:2018-11-02 04:32:46

标签: python postgresql pandas unicode

我正在使用熊猫,并像这样将数据导出为json:

import pandas as pd
df = pd.DataFrame({'a': ['Têst']})

df.to_json(orient='records', lines=True)
> u'{"a":"T\\u00east"}'

这是有道理的,因为我们有一个以00ea为前缀的Unicode字符\u,并且在转换为JSON时用\进行了转义

但是随后我使用COPY

将JSON字符串导入Postgres
buffer = cStringIO.StringIO()
buffer.write(df.to_json(orient='records', lines=True))
buffer.seek(0)

with connection.cursor() as cursor:
  cursor.copy_expert(sql="""
  COPY tmp (json_data) FROM STDIN WITH NULL AS '' ENCODING 'UTF8';
  """, file=buffer)

问题是数据库中的结果最终被

{"a": "Tu00east"}

您会看到双\\消失了。

我尝试使用CSV作为COPY模式,但是由于某些数据中存在逗号,因此将事情弄糟了,并且试图将ESCAPE字符和DELIMITER设置为其他值似乎总是会导致失败。

表列的类型为jsonb。我在文档中读到,除非DB编码为UTF8,否则PG在\ x003f上不喜欢非ASCII Unicode,在我看来,这不是问题。

我试图弄清楚为什么在这里删除了转义字符,以及如何导入到Postgres中并保存编码。

1 个答案:

答案 0 :(得分:1)

COPYDELIMITER e'\x01' QUOTE e'\x02'一起使用csv选项。我不确定这是否适用于所有可能的有效JSON,但我从未失败过。

$ psql -X testdb -c 'create table t(d jsonb)'
CREATE TABLE
$ cat foo.json
{"a":"Têst"}
$ cat foo.json | psql -X testdb -c "COPY t from stdin csv delimiter e'\x01' quote e'\x02'" 
COPY 1
$ psql -X testdb -c 'select * from t';                                                    
       d       
---------------
 {"a": "Têst"}
(1 row)