5

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

したがって、サーバー側のカーソルを反復処理しているときに別のカーソルを開始するのは好きではないようです。これにより、クライアント側のイテレータが非常に遅くなってしまったようです。

助言がありますか?

4

1 に答える 1

2

データベースへの個別の接続が必要です。最初の接続が結果セットのストリーミングでスタックしているため、挿入クエリを実行できません。

これを試して:

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()
于 2015-09-08T22:18:16.827 に答える