Postgres 不允许在 COPY 中使用 ARRAY 语法

Postgres won't allow ARRAY syntax in COPY

我有一个 table,里面有一个文本数组 (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']"

第一个测试(证明)不太正确。在这种情况下,这应该是测试:

SELECT 'ARRAY["string1", "string2", "string3"]'::text[] = '{"string1","string2","string3"}'::text[]

那是行不通的。所以我假设不,这种格式不能用于从标准输入复制。

将您的数据设为元组列表:

data = [
    (1, ['a','b']),
    (2, ['c','d'])
]

创建一个 values 语法模板来接收数据元组:

values_template = ','.join(['%s'] * len(data))

将其放入 copy 命令中:

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()