我有一个表格,其中包含文本数组 (text[]
) 类型的列。我想使用 COPY
命令复制 CSV。我正在使用 Psycopg2 的复制功能,但这个问题通常与 Postgres 相关。
似乎 Postgres 只接受格式为 {"string1","string2","string3"}
的数组,而不是 ARRAY['string1', 'string2', 'string3' ]
(见下文)。这是一个问题,因为以前一种格式转义的字符串是一个巨大的痛苦,而 Psycopg2 的 mogrify
函数以后一种格式输出数组。以第一种格式手动转义是我最后的手段,但我真的不想去那里......
有没有办法让 Postgres 采用后一种格式进行复制或其他一些解决方法?
这是我的测试:
-- proof that both syntaxes are valid and compare equal
db=# SELECT ARRAY['string1', 'string2', 'string3']::text[] = '{"string1","string2","string3"}'::text[];
?column?
----------
t
(1 row)
-- COPY works with {} syntax
db=# CREATE TEMP TABLE test(words text[]);
CREATE TABLE
db=# COPY test FROM stdin;
Enter data to be copied followed by a newline.
End with a backslash and a period on a line by itself.
>> {"string1","string2","string3"}
>> \.
COPY 1
-- COPY fails with ARRAY syntax
db=# COPY test FROM stdin;
Enter data to be copied followed by a newline.
End with a backslash and a period on a line by itself.
>> ARRAY['string1', 'string2', 'string3']
>> \.
ERROR: malformed array literal: "ARRAY['string1', 'string2', 'string3']"
DETAIL: Array value must start with "{" or dimension information.
CONTEXT: COPY test, line 1, column words: "ARRAY['string1', 'string2', 'string3']"
最佳答案
使您的数据成为元组列表:
data = [
(1, ['a','b']),
(2, ['c','d'])
]
创建一个 values
语法模板来接收数据元组:
values_template = ','.join(['%s'] * len(data))
将其放入复制
命令中:
copy_values = "copy (values {0}) to stdout (format csv)".format(values_template)
使用 mogrify
将 Python 类型适配为 Postgresql 类型:
copy_values = cursor.mogrify(copy_values, data)
copy_expert
导出文件:
f = open('file.csv', 'wb')
cursor.copy_expert(copy_values, f, size=8192)
f.close()
关于arrays - Postgres 不允许在 COPY 中使用 ARRAY 语法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39025420/