使用MySQLdb的嵌套查询

5 投票
1 回答
3908 浏览
提问于 2025-04-16 10:46

我正在尝试用Python和MySQLdb接口做以下事情:

  1. 读取一个有几百万行数据的表。
  2. 处理并修改每一行的输出。
  3. 把修改后的行放到另一个表里。

我觉得逐行处理是个不错的主意,边处理边把每一行的新数据插入到新表里。

这样做是可行的:

import MySQLdb
import MySQLdb.cursors

conn=MySQLdb.connect(
    host="somehost",user="someuser",
    passwd="somepassword",db="somedb")

cursor1 = conn.cursor(MySQLdb.cursors.Cursor)
query1 = "SELECT * FROM table1"
cursor1.execute(query1)

cursor2 = conn.cursor(MySQLdb.cursors.Cursor)

for row in cursor1:
    values = some_function(row)
    query2 = "INSERT INTO table2 VALUES (%s, %s, %s)"
    cursor2.execute(query2, values)

cursor2.close()
cursor1.close()
conn.commit()
conn.close()

但是这样做速度慢,而且占用内存,因为它使用的是客户端游标来执行SELECT查询。如果我改用服务器端游标来执行SELECT查询:

cursor1 = conn.cursor(MySQLdb.cursors.SSCursor)

结果我遇到了2014错误:

Exception _mysql_exceptions.ProgrammingError: (2014, "Commands out of sync; you can't run this command now") in <bound method SSCursor.__del__ of <MySQLdb.cursors.SSCursor object at 0x925d6ec>> ignored

看起来在使用服务器端游标时,不能再启动另一个游标。这让我只能用速度很慢的客户端迭代器。

有没有什么建议呢?

1 个回答

3

你需要一个单独的数据库连接,因为第一个连接正在处理结果集,所以你无法执行插入的查询。

试试这个:

import MySQLdb
import MySQLdb.cursors

conn=MySQLdb.connect(
    host="somehost",user="someuser",
    passwd="somepassword",db="somedb")

cursor1 = conn.cursor(MySQLdb.cursors.SSCursor)
query1 = "SELECT * FROM table1"
cursor1.execute(query1)

insertConn=MySQLdb.connect(
    host="somehost",user="someuser",
    passwd="somepassword",db="somedb")
cursor2 = inserConn.cursor(MySQLdb.cursors.Cursor)

for row in cursor1:
    values = some_function(row)
    query2 = "INSERT INTO table2 VALUES (%s, %s, %s)"
    cursor2.execute(query2, values)

cursor2.close()
cursor1.close()
conn.commit()
conn.close()
insertConn.commit()
insertConn.close()

撰写回答