8

明らかな何かが欠けている可能性がありますが、MySQLdb のオンライン ドキュメントにあるさまざまな例と私のコードがどのように異なるのかわかりません。

私はPythonのプログラミングにかなり慣れていませんが、perlの経験が豊富です。私がやろうとしていることは、早い段階で特定の良い習慣を身につけることです (perl のように、私は常に「厳格な使用; 警告を使用する」から始めます)。そのため、再利用可能な関数を独立したファイル ( funct.py) を使用して、後で時間を節約できます。

テーブルからランダムな行を選択するための次の関数があります。

def returnRandom(conn,countcol,table,field):
    cursor = conn.cursor()
    cursor.execute('SELECT MAX(%s) FROM %s',(countcol,table))
    maxRow = cursor.fetchone()[0]
    cursor.execute("SELECT MIN(%s) FROM %s",(countcol,table))
    minRow = cursor.fetchone()[0]
    randomId = random.randrange(minRow,maxRow+1,1)
    cursor.execute("SELECT ? FROM ? WHERE id >=? LIMIT 1",field,table,randomId)
    return cursor.fetchone()[0]

次のように呼び出されます。

msg = funct.returnRandom(conn,"id","testtable","data")

残念ながら、次のエラーが発生します: _mysql_exceptions.ProgrammingError: (1064, "SQL 構文にエラーがあります。1 行目の ''testtable'' 付近で使用する正しい構文については、MySQL サーバーのバージョンに対応するマニュアルを確認してください")

実行行の %s の代わりに testtable を配置すると、クエリは実行されますが、実行されているように見えます

SELECT MAX('id') FROM testtable;

もちろん「id」を返します。

これらの両方を考えると、実行しようとすると %s エントリを引用しているように見えます。それをやめる方法、または私が達成しようとしていることを実際にどのように行うべきかを誰かが説明できるかどうか疑問に思っていましたか? 関数をできるだけ汎用的にしたいので、呼び出されたときに渡されるデータに依存しています。

編集: ? に置き換えると、追加する必要があります マーク:

....
    cursor.execute('SELECT MAX(?) FROM ?',(countcol,table))
File "/usr/lib/pymodules/python2.7/MySQLdb/cursors.py", line 151, in execute
    query = query % db.literal(args)
TypeError: not all arguments converted during string formatting
4

3 に答える 3

2

メタデータに DB-API を使用することはできません。通話の外で自分で交換する必要がありexecute()ます。

query = 'SELECT MAX(%%s) FROM `%s`' % (table,)
cursor.execute(query, (countcol,))

table外部ソースからのものである場合は、明らかにこれを行うべきではありません。

于 2011-07-07T23:39:09.770 に答える
0

MySQLdb は、バッククォートではなく、単一引用符でテーブル名を引用している可能性があります。これを試して

cursor.execute('SELECT MAX(%%s) FROM `%s`' % table,(countcol))
于 2011-07-07T23:39:30.403 に答える
-1

面白い。しかし、マニュアルにはいくつかの例があります。たぶんそれは似たようなものです。

c=db.cursor()
max_price=5
c.execute("""SELECT spam, eggs, sausage FROM breakfast
          WHERE price < %s""", (max_price,))

この例では、 max_price=5 では、なぜ文字列で %s を使用するのでしょうか? MySQLdb はそれを文字列 '5' である SQL リテラル値に変換するためです。完了すると、クエリは実際には「...WHERE price < 5」となります。

c.executemany(
      """INSERT INTO breakfast (name, spam, eggs, sausage, price)
      VALUES (%s, %s, %s, %s, %s)""",
      [
      ("Spam and Sausage Lover's Plate", 5, 1, 8, 7.95 ),
      ("Not So Much Spam Plate", 3, 2, 0, 3.95 ),
      ("Don't Wany ANY SPAM! Plate", 0, 4, 3, 5.95 )
      ] )

ここでは、5 つの値の 3 つの行を挿入しています。%s しか使用していませんが、タイプ (string、int、float) が混在していることに注意してください。また、1 行のフォーマット文字列のみが含まれていることにも注意してください。MySQLdb はそれらを選択し、行ごとに複製します。

于 2015-05-06T12:59:58.060 に答える