CSV 的列具有格式text
(可以包括空行)date
和 JSON 字符串数组(类似于['a', 'b', 'c']
。我一直在尝试将该 CSV 复制到 PostgreSQL 表中(使用psycopg2
's copy_expert
,它只是执行给定的COPY
命令,如果这很重要)
表是用
CREATE TABLE posts(
id SERIAL PRIMARY KEY,
text TEXT NOT NULL,
created_date TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
rubrics jsonb[] NOT NULL
);
复制命令是
COPY posts(text, created_date, rubrics)
FROM STDIN
WITH CSV HEADER
STDIN
CSV 文件在哪里。
我得到的错误是
malformed array literal: "['a', 'b', 'c']"
DETAIL: "[" must introduce explicitly-specified array dimensions.
CONTEXT: COPY posts, line 15, column rubrics: "['a', 'b', 'c']"
我已经尝试了所有 4 种与 JSON 相关的数据类型(json
并且jsonb
有和没有[]
or [3]
),包括方括号会产生上述错误,而省略它们(rubrics jsonb NOT NULL
创建时)会产生新的错误:
invalid input syntax for type json
DETAIL: Token "'" is invalid.
CONTEXT: JSON data, line 1: ['...
COPY posts, line 15, column rubrics: "['a', 'b', 'c']"
除了手动修复要使用的 .csv{}
而不是[]
在复制之前,我还有什么办法吗?感觉就像我一样,但除了几个有点但不完全相关的问题之外,我真的找不到任何东西。
关于评论的更新
我已将表创建更改为
CREATE TABLE posts(
id SERIAL PRIMARY KEY,
text TEXT NOT NULL,
created_date TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
rubrics jsonb NOT NULL
);
并在 CSV 中留下一个条目进行测试,所以看起来像这样
text,created_date,rubrics
"Lorem
Ipsum
Test",2019-07-25 12:42:13,'["f", "o", "o"]'
我尝试过的事情和我得到的错误
按原样使用 CSV:
extra data after last expected column
CONTEXT: COPY posts, line 6: ""Lorem
Ipsum
Test",2019-07-25 12:42:13,'["f", "o", "o"]'"
""
数组周围的另外一对( "'["f", "o", "o"]'"
)
invalid input syntax for type json
DETAIL: Token "'" is invalid.
CONTEXT: JSON data, line 1: '...
COPY posts, line 6, column rubrics: "'[f, o, o]'"
根本没有引号(只有["f", "o", "o"]
)
extra data after last expected column
CONTEXT: COPY posts, line 6: ""Lorem
Ipsum
Test",2019-07-25 12:42:13,["f", "o", "o"]"
双引号代替单引号 ( "["f", "o", "o"]"
)
invalid input syntax for type json
DETAIL: Token "f" is invalid.
CONTEXT: JSON data, line 1: [f...
COPY posts, line 6, column rubrics: "[f, o, o]"
外双引号,内单引号 ( "['f', 'o', 'o']"
)
invalid input syntax for type json
DETAIL: Token "'" is invalid.
CONTEXT: JSON data, line 1: ['...
COPY posts, line 6, column rubrics: "['f', 'o', 'o']"
毕竟我正在使用的 Python 库有问题吗?
JSON 是具有标准化语法的封装层,输入中的 JSON 字段必须遵守该语法。
CSV 是在顶部应用的另一层封装,其语法在 rfc 4180 中标准化程度较低。正如 RFC 中提到的,读取或写入 CSV 的程序并不总是严格遵守所有这些规则,但在引用规则方面,Postgres 是符合的。
JSON 在字符串文字周围使用双引号,因此问题中在字符串周围使用单引号的所有尝试对于 JSON 解析器都是无效的
CSV 要求双引号加倍,请参阅 rfc 4180 的规则 #5 和 #7,因此所有尝试在 JSON 中使用双引号而不为 CSV 加倍或不将整个字段括在双引号中的所有尝试对于 CSV 解析器都是无效的。
您的示例稍作编辑以符合 CSV 和 JSON 确实有效:
如果你想要一个 JSON 对象的 Postgres 数组,那会更复杂,因为将 Postgres 数组表示为文本需要使用自己的语法规则
rubrics
进行另一层封装,因此必须使用 COPY 生成要导入的有效数据JSON 引用 -> postgres 数组引用 -> CSV 引用
但如您的示例中所见,您似乎不需要 JSON 对象的 Postgres 数组作为列,而是需要包含 JSON 数组的单个 JSON 值。