2

次のようなステートメントを実行しようとすると、次のようになります。

cursor.executemany("""INSERT INTO `test` (`id`,`data`,`time_added`) 
                      VALUES (%s, %s, NOW())""", [(i.id, i.data) for i in items])

MySQLdbは、挿入する行のリストを展開すると、その括弧が値ブロックの終わりと見なされるため、NOW()の)を詰まらせているようです。つまり、クエリは次のようになります。

('1', 'a', NOW(), ('2','b', NOW(), ('3','c',NOW())

そしてMYSQLは構文エラーを報告します。代わりに、次のようになります。

('1', 'a', NOW()), ('2','b', NOW()), ('3','c',NOW())

NOW()を回避する方法があるはずですが、その方法がわかりません。タプルに「NOW()」を追加しても機能しません。これは、NOW()が引用符で囲まれ、DBによって関数呼び出しではなく文字列として解釈されるためです。

現在のタイムスタンプをデフォルト値として使用してこれを回避することはオプションではありません。これは例です。今だけでなく、さまざまなdb関数を使用してこの種のことを行う必要があります。

ありがとう!

4

1 に答える 1

1

以下の方法は理想からは程遠いですが、残念ながら、それが私が知っている唯一の方法です。

connection.literalアイデアは、引数をエスケープするために使用して、SQLを手動で構築することです。

cursor=connection.cursor()
args=[(1,'foo'),(2,'bar')]
sql=('INSERT INTO `foo` (`fooid`,`data`,`time_added`) VALUES '
     +','.join(
         ['(%s,%s,NOW())'%connection.literal(arg)
          for arg in args]))
cursor.execute(sql)

これはひどいように見え、肌を這わせる可能性がありますが、MySQLdbが何をしているのかを(/usr/lib/pymodules/python2.6/MySQLdb/cursors.pyで)内部で見るとcursors.executemany、これはその関数が実行しているのと同じ行ですが、正規表現cursors.insert_valuesがネストされた括弧を正しく解析していないために混乱が生じています。(eek!)


MySQLdbの代わりとなるoursqlをインストールしたところですが、それを報告できてうれしいです。

sql='INSERT INTO `foo` (`fooid`,`data`,`time_added`) VALUES (?,?,NOW())'
cursor.executemany(sql,args)

oursqlで期待どおりに動作します。

于 2011-02-02T21:42:58.430 に答える