使用大型数据集调用cursor.fetchall()时,python脚本会挂起

时间:2015-04-10 01:18:39

标签: python mysql-connector

我有一个返回超过125K行的查询。

目标是编写一个迭代遍历行的脚本,并为每个行填充第二个表,其中包含从查询结果处理的数据。

为了开发脚本,我创建了一个包含一小部分数据(4126行)的重复数据库

在小型数据库中,以下代码有效:

import os
import sys
import random

import mysql.connector

cnx = mysql.connector.connect(user='dbuser', password='thePassword',
                          host='127.0.0.1',
                          database='db')
cnx_out = mysql.connector.connect(user='dbuser', password='thePassword',
                          host='127.0.0.1',
                          database='db')

ins_curs = cnx_out.cursor()

curs = cnx.cursor(dictionary=True)
#curs = cnx.cursor(dictionary=True,buffered=True) #fail

with open('sql\\getRawData.sql') as fh:
    sql = fh.read()

curs.execute(sql, params=None, multi=False)
result = curs.fetchall()  #<=== script stops at this point
print len(result) #<=== this line never executes

print curs.column_names

curs.close()
cnx.close()
cnx_out.close()
sys.exit()

curs.execute(sql, params=None, multi=False)在大型和小型数据库上都取得了成功。 如果我在循环中使用curs.fetchone(),我可以阅读所有记录。

如果我改变了这条线:

curs = cnx.cursor(dictionary=True)

阅读:

curs = cnx.cursor(dictionary=True,buffered=True)

脚本挂起curs.execute(sql, params=None, multi=False)

我找不到有关fetchall()的任何限制的文档,也无法找到任何增加缓冲区大小的方法,也无法判断我甚至需要多大的缓冲区。

没有例外。

我该如何解决这个问题?

1 个答案:

答案 0 :(得分:1)

我遇到了同样的问题,首先是一个返回~70k行的查询,然后是一个只返回大约2k行的查询(对我来说RAM也不是限制因素)。我从使用mysql.connector(即mysql-connector-python包)切换到MySQLdb(即mysql-python包),然后能够在没有问题的情况下对大型查询进行fetchall()。这两个软件包似乎都遵循python DB API,所以对我来说MySQLdb是mysql.connector的替代品,在设置连接的行之外不需要更改代码。 YMMV如果您正在利用有关mysql.connector的特定内容。

实际上,如果你没有特定的理由使用mysql.connector,解决方法就是切换到一个更好用的包!