5

UPDATE
以下のネイサンの提案に従ってexecute()に行のリストを渡した後、コードはさらに実行されますが、execute関数でスタックします。エラーメッセージは次のとおりです。

    query = query % db.literal(args)
TypeError: not all arguments converted during string formatting

したがって、まだ機能していません。なぜ今タイプエラーがあるのか​​誰か知っていますか?
更新を終了

.xls形式の大きなメーリングリストがあります。xlrdでpythonを使用して、xlsファイルから2つのリストに名前と電子メールを取得しています。次に、それぞれの名前と電子メールをmysqlデータベースに入れたいと思います。この部分にはMySQLdbを使用しています。明らかに、すべてのリスト項目に対して挿入ステートメントを実行したくありません。
これが私がこれまでに持っているものです。

from xlrd import open_workbook, cellname
import MySQLdb

dbname = 'h4h'
host = 'localhost'
pwd = 'P@ssw0rd'
user = 'root'

book = open_workbook('h4hlist.xls')
sheet = book.sheet_by_index(0)
mailing_list = {}
name_list = []
email_list = []

for row in range(sheet.nrows):
    """name is in the 0th col. email is the 4th col."""
    name = sheet.cell(row, 0).value  
    email =  sheet.cell(row, 4).value
    if name and email:
        mailing_list[name] = email

for n, e in sorted(mailing_list.iteritems()):
    name_list.append(n)
    email_list.append(e)

db = MySQLdb.connect(host=host, user=user, db=dbname, passwd=pwd)
cursor = db.cursor()
cursor.execute("""INSERT INTO mailing_list (name,email) VALUES (%s,%s)""",
              (name_list, email_list))

カーソル実行時の問題。これはエラーです。_mysql_exceptions.OperationalError: (1241, 'Operand should contain 1 column(s)')最初にクエリをvarに入れようとしましたが、execute()にタプルを渡すことに関するメッセージが表示されました。

私は何が間違っているのですか?これも可能ですか?

リストは膨大で、インサートをループに入れる余裕はありません。LOAD DATA INFILEの使用を検討しましたが、ファイルやクエリのフォーマット方法がよくわからず、MySQLのドキュメントを読まなければならないときに目が出血します。私おそらくいくつかのオンラインxlsからmysqlへのコンバーターを使用できることを知っていますが、これは私にとっても学習演習です。もっと良い方法はありますか?

4

4 に答える 4

18

executemany()行のリストを提供する必要があります。名前と電子メールを別々のリストに分割する必要はありません。両方の値を含む1つのリストを作成するだけです。

rows = []

for row in range(sheet.nrows):
    """name is in the 0th col. email is the 4th col."""
    name = sheet.cell(row, 0).value  
    email =  sheet.cell(row, 4).value
    rows.append((name, email))

db = MySQLdb.connect(host=host, user=user, db=dbname, passwd=pwd)
cursor = db.cursor()
cursor.executemany("""INSERT INTO mailing_list (name,email) VALUES (%s,%s)""", rows)

更新:@JonClementsが言及しているように、そうではexecutemany()ないはずexecute()です。

于 2012-10-22T22:35:55.047 に答える
7

修正するには、メソッドTypeError: not all arguments converted during string formattingを使用する必要があります。cursor.executemany(...)これは、反復可能なタプル (複数の行) を受け入れる一方でcursor.execute(...)、パラメーターが単一の行の値であると想定しているからです。

コマンドの実行後、 を使用して、トランザクションがコミットされ、データベースで変更がアクティブになっていることを確認する必要がありますdb.commit()

于 2012-10-22T23:47:51.907 に答える
3

コードの高性能に関心がある場合は、この回答の方が適している可能性があります。

メソッドと比較する excutemanyと、以下executeははるかに高速になります。

INSERT INTO mailing_list (name,email) VALUES ('Jim','jim@yahoo.com'),('Lucy','Lucy@gmail.com')

@Nathan Villaescusa からの回答を簡単に変更して、新しいコードを取得できます。

cursor.execute("""INSERT INTO mailing_list (name,email) VALUES (%s)""".format(",".join(str(i) for i in rows))

ここに私自身のテスト結果があります:

excutemany:10000 runs takes 220 seconds

execute:10000 runs takes 12 seconds.

速度差は約15倍になります。

于 2017-09-29T08:31:35.783 に答える