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()
我有一个 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()