首页 > 解决方案 > 将 json 导入 Postgres 时出现编码问题

问题描述

我正在使用熊猫,并将数据导出为 json,如下所示:

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

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

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

但随后我将 JSON 字符串导入 PostgresCOPY

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类型。我在文档中读到 PG 不喜欢 \x003f 上的非 ASCII Unicode,除非 DB 编码是 UTF8,在我的情况下,这应该不是问题。

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

标签: pythonpostgresqlpandasunicode

解决方案


COPY对,使用 csv 选项DELIMITER e'\x01' QUOTE e'\x02'。我不确定这是否适用于所有可能的有效 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)

推荐阅读