Я пытаюсь добиться следующего, используя Python и интерфейс MySQLdb:
- Прочитайте содержимое таблицы, содержащей несколько миллионов строк.
- Обработайте и измените вывод каждой строки.
- Поместите измененные строки в другую таблицу.
Мне кажется разумным перебирать каждую строку, обрабатывать «на лету», а затем вставлять каждую новую строку в новую таблицу «на лету».
Это работает:
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
Так что, похоже, ему не нравится запускать другой курсор во время итерации над курсором на стороне сервера. Что, кажется, оставляет меня застрявшим с очень медленным итератором на стороне клиента.
Какие-либо предложения?
INSERT INTO ... SELECT
, гдеSELECT
выполняет логику вашегоsome_function
было выполнять? MySQL может многое сделать прямо внутри запроса. - person Dan Grossman   schedule 28.01.2011