【问题标题】:Using COPY instead of INSERT within python for postgresql在 python 中为 postgresql 使用 COPY 而不是 INSERT
【发布时间】:2019-08-13 21:06:45
【问题描述】:

我有一个 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 需要后者。

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

【问题讨论】:

  • 您不会像最初复制 csv 那样格式化数据以进行复制
  • 不要使用copy。请改用execute_values
  • @ClodoaldoNeto:重点是我想使用 COPY 来提高速度。使用 insert 和 execute_values 很慢。
  • execute_values 的全部意义在于它比insert 快得多。
  • 如果使用 csv,您必须使用 copy_expert() 以便您可以传递所需的格式参数。搜索一下,很多例子。

标签: python postgresql csv


【解决方案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。这是更灵活的选择。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-10-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-30
    • 1970-01-01
    • 2018-05-08
    • 1970-01-01
    相关资源
    最近更新 更多