【问题标题】:MysqlDB - query is killedMysqlDB - 查询被杀死
【发布时间】:2018-06-14 06:23:48
【问题描述】:

我有一个 python 脚本,它试图转储一个包含 750 万行的表,但大约 20 秒后的查询被杀死。 我使用 MysqlDB 连接远程数据库。我读到 MySQL --quick 选项可能会有所帮助,因为它不会缓存每个查询结果。 如何在我的 python 脚本中使用这个选项?

编辑: 我用过pdb。似乎执行了查询,因为所有 750 万行都存在于变量“rows”中。 这是我的脚本:

def dumpDatasetToCsv(self, name):
    cur = self._con.cursor()
    res = cur.execute(self._query)
    rows = cur.fetchall()
    column_names = [i[0] for i in cur.description]
    dumpFilePath=cfg.EtlConfiguration.exportDirectory +  self._dataSetName+ '-' + self.csvFileSuffix + '.csv'
    fp = open(dumpFilePath ,'w')
    myFile = csv.writer(fp, lineterminator = '\n') 
    list_to_export=[]
    for row in rows: list_to_export.append(list(row))
    for row in list_to_export: row.insert(1, self.csvFileSuffix)
    myFile.writerows(list_to_export)
    fp.close()

代码在“for row in rows: list_to_export.append(list(row))”行崩溃

此外,当我使用 pdb 并在上述行之前停止执行脚本时,我只是逐行粘贴代码的其余行,一切正常。输出文件已创建。

【问题讨论】:

  • 我还没有在 Python 的 MySQLdb 中找到 --quick 参数,但也许你可以使用 fetch_row 函数来完成它,它遍历一个表以转储它。 MySQLdb documentation
  • 我编辑了我的帖子。机器似乎内存不足,但没有执行查询。
  • 显然这是由于内存不足,因为您正在尝试获取所有行并同时转储它们。要继续处理大量行,您必须将它们处理成块,就像 @user31415629 和我对您说的那样。
  • @czyzyk14 你所在的机器可能只有足够的内存来保存 750 万行一次,但是当你在它崩溃的行中复制它们时,它会用完。无论如何,如果行数增加,您的方法最终还是会失败。对于大型数据集,您应该始终在任何地方进行分块,这样您一次最多只能在内存中保留 1000(或很多)行。
  • @user31415629 谢谢!我将尝试不同的 fetchmany 值,但 10K 似乎没问题。

标签: python mysql mysql-python


【解决方案1】:

750 万行可能会导致您的内存填满并导致进程被终止。你想做这样的事情:

with open('outfile.csv', 'w') as f:
   while True:
      rows = cursor.fetchmany(1000)
      if not rows:
          break
      f.write(...)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-08-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-08
    相关资源
    最近更新 更多