Вложенные запросы с использованием MySQLdb - PullRequest
5 голосов
/ 28 января 2011

Я пытаюсь добиться следующего, используя 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 Ответ

2 голосов
/ 09 сентября 2015

Вам необходимо отдельное соединение с базой данных, поскольку первое соединение застряло с потоковой передачей результирующего набора, вы не можете выполнить запрос вставки.

Попробуйте это:

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()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...