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

标签 arrays postgresql csv etl psycopg2

我有一个表格,其中包含文本数组 (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/

相关文章:

sql - 模式是否应该始终在 SQL 语句中显式定义?

python - 通过 Scrapy (Python) 将抓取的数据导出到 csv 后,我在文件中得到了像 ' 这样的字符

sql-server - 使用 PowerShell 将 CSV 文件中的数据导入带有附加列的 SQL Server

javascript - 如何将数组名称存储在对象中以便稍后动态选择?

Javascript 使用 map() 和 Iterator 将对象数组分成多个数组

java - 如何将一个大数(精度 19,小数位数 2)四舍五入为整数?

ruby-on-rails - Rails 从所有 Select * 类型查询中隐藏特定记录

python - 值错误: time data '140120 1520' does not match format '%Y-%m-%d %H:%M:%S'

arrays - Ruby:将 int 和存储转换为数组

javascript - 对象名称可以是数字吗?