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

Vor*_*man 5 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()
Run Code Online (Sandbox Code Playgroud)

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

如果我改变了这条线:

curs = cnx.cursor(dictionary=True)
Run Code Online (Sandbox Code Playgroud)

阅读:

curs = cnx.cursor(dictionary=True,buffered=True)
Run Code Online (Sandbox Code Playgroud)

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

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

没有例外.

我该如何解决这个问题?

mac*_*tyr 1

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

务实地说,如果您没有特定原因使用 mysql.connector,解决方案就是切换到效果更好的包!