web-dev-qa-db-ja.com

PythonのSQLステートメントで変数を使用する方法は?

わかりましたので、私はPythonの経験がありません。

次のPythonコードがあります。

cursor.execute("INSERT INTO table VALUES var1, var2, var3,")

var1は整数、var2およびvar3は文字列です。

クエリテキストの一部として変数を含めるpythonなしで変数名を書くにはどうすればよいですか?

78
user111606
cursor.execute("INSERT INTO table VALUES (%s, %s, %s)", (var1, var2, var3))

パラメーターはTupleとして渡されることに注意してください。

データベースAPIは、変数の適切なエスケープと引用を行います。文字列フォーマット演算子(%)を使用しないように注意してください。

  1. エスケープや引用は行いません。
  2. 制御されていない文字列形式の攻撃を受けやすい SQLインジェクション
81
Ayman Hourieh

Python DB-APIの異なる実装では、異なるプレースホルダーを使用することが許可されているため、使用しているプレースホルダーを確認する必要があります(MySQLdbなど)。

cursor.execute("INSERT INTO table VALUES (%s, %s, %s)", (var1, var2, var3))

または(例:Python標準ライブラリのsqlite3を使用):

cursor.execute("INSERT INTO table VALUES (?, ?, ?)", (var1, var2, var3))

またはまだ(VALUESの後に(:1, :2, :3)、または "named styles" (:fee, :fie, :fo)または(%(fee)s, %(fie)s, %(fo)s)があり、マップの代わりにdictをexecuteに渡すことができます)。使用しているDB APIモジュールのparamstyle文字列定数を確認し、 http://www.python.org/dev/peps/pep-0249/ でparamstyleを探して、すべてのパラメータを渡すスタイルは次のとおりです!

59
Alex Martelli

たくさんの方法。 DO N'T実際のコードでは最も明白なもの(%s%)を使用します。 攻撃

ここでコピーアンドペーストsqlite3のpydocから

# Never do this -- insecure!
symbol = 'RHAT'
c.execute("SELECT * FROM stocks WHERE symbol = '%s'" % symbol)

# Do this instead
t = ('RHAT',)
c.execute('SELECT * FROM stocks WHERE symbol=?', t)
print c.fetchone()

# Larger example that inserts many records at a time
purchases = [('2006-03-28', 'BUY', 'IBM', 1000, 45.00),
             ('2006-04-05', 'BUY', 'MSFT', 1000, 72.00),
             ('2006-04-06', 'SELL', 'IBM', 500, 53.00),
            ]
c.executemany('INSERT INTO stocks VALUES (?,?,?,?,?)', purchases)

必要な場合のその他の例:

# Multiple values single statement/execution
c.execute('SELECT * FROM stocks WHERE symbol=? OR symbol=?', ('RHAT', 'MSO'))
print c.fetchall()
c.execute('SELECT * FROM stocks WHERE symbol IN (?, ?)', ('RHAT', 'MSO'))
print c.fetchall()
# This also works, though ones above are better as a habit as it's inline with syntax of executemany().. but your choice.
c.execute('SELECT * FROM stocks WHERE symbol=? OR symbol=?', 'RHAT', 'MSO')
print c.fetchall()
# Insert a single item
c.execute('INSERT INTO stocks VALUES (?,?,?,?,?)', ('2006-03-28', 'BUY', 'IBM', 1000, 45.00))
35
Kashyap

http://www.amk.ca/python/writing/DB-API.html

変数の値をステートメントに単純に追加する場合は注意してください:';DROP TABLE Users;'という名前のユーザーを想像してください-カーソルを使用するときにPythonが提供するsqlエスケープを使用する必要があるのはそのためです適切な方法で実行する。 URLの例は次のとおりです。

cursor.execute("insert into Attendees values (?, ?, ?)", (name,
seminar, paid) )
20
Numlock