13

是否可以通过 psycopg2 运行以下命令?如果是这样,我该怎么做?

COPY table_name(col1,col2) FROM 'path/to/file.csv' WITH HEADER DELIMITER ',' CSV;
4

4 回答 4

21

是的!

您可以使用以下copy_from方法

import psycopg2
dbname=...
user=...
password=...
host=...
port=...
con = psycopg2.connect(database=dbname,user=user,password=password,host=host,port=port)
cur = con.cursor()    
f = open('path/to/file.csv')
cur.copy_from(f, 'test', columns=('col1', 'col2'), sep=",")
con.commit()
con.close()
于 2014-06-10T21:07:39.380 回答
3

谷歌搜索psycopg2 copy发现,作为我的第一击,psycopg 手册,其中包括使用客户端的说明COPY

如果您想要服务器端COPY,您只需像任何其他 SQL 一样运行该语句。

如上所述,该命令没有任何意义。我想你打算写一个COPY ... TOorCOPY ... FROM命令并在隐藏真实文件名等的同时破坏它。

于 2013-07-10T01:12:05.433 回答
1

copy_from命令对基本用例很有用:

with open('path/to/file.csv') as f:
    cursor.copy_from(f, 'table_name', columns=('col1', 'col2'), sep=',')

请注意,在按照您的问题所述复制 CSV 数据时,各种问题将阻止您使用 copy_from - 标题行、引用值、包含逗号的值。可以使用copy_expert带有简单手动组合的 COPY 查询的命令导入 CSV:

with open('path/to/file.csv') as f:
    cursor.copy_expert('COPY table_name(col1, col2) FROM STDIN WITH HEADER CSV', f)
于 2021-01-25T15:51:25.430 回答
-2

有一个交易破坏者使用copy_from: 它不识别带引号的字段,例如,如果您有一个值with, a comma并使用 csv.writer 那么它被写为,"with, a comma". psycopg2 无法识别这一点(请参阅@shrinathM 的引号注释)。

这就是为什么在大多数情况下您需要回退到更基本的copy_expert.

也就是说,我在使用时发现的另一件困难的事情COPY是了解 CSV 必须如何构建才能使 postgres 正确使用它。这是一个使用而不是文件的基本代码StringIO

以下解决方案向您展示了如何使用 python 编写 CSV 以及如何使用 copy_expert。如果您已经拥有 CSV,那么您只需要最后一行。

import io
import csv
import datetime 

f = io.StringIO()
w = csv.writer(f)
data = [
  ['Hans', [1,2,3], True],
  ['Kurt', [4], False],
]
columns = ['name', 'ids', 'has_foo']
print('convert to csv format')
for l_in in data:
  l_out = []
  for v in l_in:
    if v == None:
      l_out.append('')
    elif type(v) in [str, int, datetime.date]:
      l_out.append(str(v))
    elif type(v) in [list, set, tuple]:
      l_out.append('{' + ','.join(str(i) for i in v) + '}')
    elif type(v) == bool:
      if v:
        l_out.append('t')
      else:
        l_out.append('f')
    else:
      print(f'unsupported type {type(v)}, writing str()')
      l_out.append(str(v))
  w.writerow(l_out)
print('actual copy')
f.seek(0)
cursor = conn.cursor()
cursor.copy_expert(f"""COPY my_table ({','.join(columns)}) FROM STDIN WITH (FORMAT CSV)""", f)
conn.commit()
于 2020-07-06T06:56:28.667 回答