在python中使用COPY代替INSERT for postgresql

时间:2017-09-21 07:59:48

标签: python postgresql csv

我有一个python脚本,使用INSERT向Postgres表添加许多条目。我想用COPY代替速度。 This answer到达那里,但没有指示如何格式化列表,布尔等。

使用INSERTpsycopg2会为您处理格式:

foo = [0,1,2]
bar = '"Hello," she said'
cur.execute("insert into table (foo, bar) values (%s, %s)", (foo, bar))

但是,这不适用于复制,因为您必须使用csv格式的数据:

foo = [0,1,2]
bar = '"Hello," she said'
csv_string = "\t".join(str(foo), str(bar))
buf = io.StringIO()
buf.write(csv_string)
buf.seek(0)
cur.copy_from(buf, 'table')
# Does not work, as data is not formatted properly

使用csv writer进行格式化也不起作用:

writer = csv.writer(buf)
csv_writer.writerow([foo,bar])
buf.seek(0)
cur.copy_from(buf, 'table')
# Fails on lists which get formatted as [], fails on NULL values

如何将数据格式化为Postgres兼容的CSV字符串?我尝试了cur.mogrify,但它将列表格式化为ARRAY[0,1,2]而不是{0,1,2},而copy_from则需要后者。

我想我可以尝试使用自己的字符串格式化程序,但肯定有更好的方法吗?

1 个答案:

答案 0 :(得分:1)

以下示例有效:

foo = [0,1,2]
bar = '"Hello," she said'
csv_string = str(foo)+"\t"+ str(bar)
print(csv_string)
buf = io.StringIO()
buf.write(csv_string)
buf.seek(0)
cur.copy_from(buf, 'table')

您的代码与上面的代码之间的区别是第3行(csv_string = ...)。

无论如何,我建议使用copy_expert而不是copy_from。这是更灵活的选项。