【问题标题】:Copy (from) csv with heades in postgres with python使用python在postgres中复制(从)带有标题的csv
【发布时间】:2014-10-23 08:29:36
【问题描述】:

我正在尝试在 python 脚本中从 CSV 文件填充表格。

后面的 SQL 语句运行没有错误:

COPY registro
FROM '/home/pablo/Escritorio/puntos/20140227.csv'
DELIMITER ','
CSV header;

CSV 有标头,使用header 参数,导入时不会出错。

当我从我的 python 脚本执行它时,问题就来了。我发现不尝试导入标头的唯一方法是使用 copy_expert() 方法。运行下面的 Python 脚本后,我没有收到错误消息,但表仍然为空。

任何可能的线索?或者可能有任何其他方式从带有标题的 CSV 复制表格?

谢谢。

#/usr/bin/env python
# -*- coding: utf-8 -*-
import psycopg2
import os
import glob
DSN = "dbname=gps user=postgres host=localhost"
con = psycopg2.connect(DSN)
cur = con.cursor()
my_file = open('/home/pablo/Escritorio/puntos/20140227.csv')
#This is only a test file, not all the directory
sql = "COPY registro FROM stdin DELIMITER \',\' CSV header;"
cur.copy_expert(sql, my_file)
cur.close()
con.close()

【问题讨论】:

标签: python sql postgresql csv psycopg2


【解决方案1】:

我建议先在 python 中处理 csv 文件。最好将从 csv 文件中提取的数据结构化为行/列(在 python 中,这将是嵌套列表或元组列表),然后您可以基于该数据迭代地构造和执行 SQL 命令。

使用 csv 库与 csv 文件进行交互,请查看此处的文档:https://docs.python.org/2/library/csv.html。它非常用户友好,可以帮助您解决很多问题。

这是一种不使用csv 的方法(因为我记不起所有功能),但是最好不要使用这种方法:

#/usr/bin/env python
# -*- coding: utf-8 -*-
import psycopg2
import os
import glob
DSN = "dbname=gps user=postgres host=localhost"
con = psycopg2.connect(DSN)
cur = con.cursor()

# 'rb' used as I don't know the encoding of your file
# just use r if it's in utf-8 or a known/consistent charset
with open(file,'rb') as open_file:
    my_file = open_file.read().decode('utf-8','ignore')

data = my_file.splitlines()
data = [r.split(delimiter) for r in data]

data = data[1:] # get rid of headers

for r in data:
     # create command
     # cur.execute(command)

【讨论】:

  • 这一行可以帮助我从 csv/json 读取数据并复制到 vertica 中的 flex 中。谢谢-:) my_file = open_file.read().decode('utf-8','ignore')
【解决方案2】:

我会在cur.copy_expert() 之后尝试con.commit()

此外,如果数据集很大,我会避免像上面 Sam P. 指出的那样对文件进行预处理和逐行上传。 cur.copy_expert() 明显更快。

conn = psycopg2.connect('postgresql://scott:tiger@localhost:5432/database')
cur = conn.cursor()
copy_sql = """
           COPY table_name FROM stdin WITH CSV HEADER
           DELIMITER as ','
           """
with open(path, 'r') as f:
    cur.copy_expert(sql=copy_sql, file=f)
    conn.commit()
    cur.close()

【讨论】:

  • 不应该也关闭连接吗?
  • copy_from(file, table_name, feature=value) 方法是否有 header=true 的选项?
  • @aydow,关闭连接不是一个坏主意。我应该将它包含在我的原始帖子中,而不是 with 块
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-10-30
  • 2016-09-18
  • 2015-07-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多