【问题标题】:Import Data to SQL using Python使用 Python 将数据导入 SQL
【发布时间】:2019-01-28 16:53:15
【问题描述】:

我需要将 30k 行数据从 CSV 文件导入 Vertica 数据库。我尝试过的代码需要一个多小时才能完成。我想知道是否有更快的方法来做到这一点?我尝试使用 csv 进行导入,也尝试通过循环插入数据帧来进行导入,但这还不够快。事实上,它太慢了。你能帮帮我吗?

rownum=df.shape[0]
for x in range(0,rownum):
 a=df['AccountName'].values[x]
 b=df['ID'].values[x]
 ss="INSERT INTO Table (AccountName,ID) VALUES (%s,%s)"
 val=(a,b)
 cur.execute(ss,val)

connection.commit()

【问题讨论】:

  • 立即尝试可能是val = (df['AccountName'].values.tolist(), df['ID'].values.tolist()),然后在没有for 循环的情况下使用cur.executemany(ss, val)。那应该更快,但我不确定是否有进一步的改进。此外,缩进 1 个空格使此代码难以阅读;你确定connection.commit() 绝对不在for 循环中吗?犯这个错误只需要1 个空格。我建议你按照 PEP8 规则使用 4 个空格

标签: python sql vertica


【解决方案1】:

您想使用COPY 命令 (COPY)。

COPY Table FROM '/path/to/csv/file.csv' DELIMITER ',';

这比一次插入每一行要快得多。

由于您使用的是 python,我会推荐 vertica_python 模块,因为它在其光标对象 (vertica-python GitHub page) 上有一个非常方便的复制方法。

在vertica-python中使用COPY的语法如下:

with open('file.csv', 'r') as file:
    csv_file = file.read()
    copy_cmd = "COPY Table FROM STDIN DELIMITER ','"
    cur.copy(copy_cmd, csv_file)
    connection.commit()

您可以做的另一件事是压缩 csv 文件以加快该过程。 Vertica 可以读取 gzip、bzip 和 lzo 压缩文件。

with open('file.csv.gz', 'r') as file:
    gzipped_csv_file = file.read()
    copy_cmd = "COPY Table FROM STDIN GZIP DELIMITER ','"
    cur.copy(copy_cmd, gzipped_csv_file)
    connection.commit()

复制压缩文件将减少网络时间。因此,您必须确定压缩 csv 文件所花费的额外时间是否可以弥补复制压缩文件所节省的时间。在我处理过的大多数情况下,压缩文件是值得的。

【讨论】:

  • 嘿,非常感谢您的帮助。我能把时间缩短到不到一分钟!太棒了,非常感谢!
  • 只是,并不是所有的行都被复制了。我有大约 21900 行,我只在我的 sql 表中看到 21300。您对此有何看法?
  • 嗨 A.Saunders,你能帮我看看为什么有些行会被删除吗?谢谢!
  • @LaxMandis 您可以使用REJECTED DATAEXCEPTIONS 找出缺少哪些行以及原因。您需要为每个指定路径。拒绝的数据将显示哪些行没有被复制,异常显示错误是什么。语法为COPY Table FROM STDIN GZIP DELIMITER ',' REJECTED DATA '/path/to/rejections.txt' EXCEPTIONS '/path/to/exceptions.txt';。当我使用 copy 语句时,我总是包含这些选项,但为简单起见,将它们排除在我上面的解释之外。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-14
  • 1970-01-01
  • 2016-10-22
相关资源
最近更新 更多