私はPythonでそれほど経験はありません。PythonのSQL文で変数を使用する方法は?
私は次のPythonコードを持っている:var1
は整数
cursor.execute("INSERT INTO table VALUES var1, var2, var3,")
を、var2
& var3
は文字列です。
Pythonを使用せずに変数名をクエリテキストの一部として書き込むにはどうすればよいですか?
私はPythonでそれほど経験はありません。PythonのSQL文で変数を使用する方法は?
私は次のPythonコードを持っている:var1
は整数
cursor.execute("INSERT INTO table VALUES var1, var2, var3,")
を、var2
& var3
は文字列です。
Pythonを使用せずに変数名をクエリテキストの一部として書き込むにはどうすればよいですか?
cursor.execute("INSERT INTO table VALUES (%s, %s, %s)", (var1, var2, var3))
パラメータはタプルとして渡されることに注意してください。
データベースAPIは、適切なエスケープと変数の引用を行いません。それはどんなエスケープや引用を行いません
%
)を使用しないように注意してください。http://www.amk.ca/python/writing/DB-API.html
あなたは、単にあなたの文に変数の値を追加するときには注意してください: 自身';DROP TABLE Users;'
命名ユーザー想像して - ときはPythonがあなたのために提供され、あなたはSQLのエスケープを使用する必要がある理由です をまともな方法でcursor.executeを使用してください。 URLでの例は次のとおりです。あなたが使用しているどちら見つける必要がありますので、PythonのDB-APIの
cursor.execute("insert into Attendees values (?, ?, ?)", (name,
seminar, paid))
実際には、SQLはエスケープしていません。これは可変バインディングであり、はるかに簡単で直接的です。値は解析後にSQLステートメントにバインドされ、あらゆる注入攻撃から免除されます。 –
"リトルボビーテーブル、我々は彼を呼び出します。"あなたの入力をサニタイズする。 https://xkcd.com/327/ – mattmc3
異なる実装は、異なるプレースホルダを使用することを許可されている - それは、例えばと(かもしれませんMySQLdbは):Pythonの標準ライブラリからsqlite3のと
cursor.execute("INSERT INTO table VALUES (%s, %s, %s)", (var1, var2, var3))
か(例):
cursor.execute("INSERT INTO table VALUES (?, ?, ?)", (var1, var2, var3))
や他の人はまだ(VALUES
後にあなたが(:1, :2, :3)
を持つことができ、または"名前付きスタイル" (:fee, :fie, :fo)
または(%(fee)s, %(fie)s, %(fo)s)
ここでは、execute
の2番目の引数としてマップの代わりにdictを渡します。使用しているDB APIモジュールの文字列定数paramstyle
を確認し、パラメータタイプがすべてであるかどうかを調べるには、http://www.python.org/dev/peps/pep-0249/のparamstyleを探してください。
外部SQLスクリプトでも同じことが可能ですか? – Novitoll
さまざまな方法があります。 は、最も明白なもの(%s
と%
)を実際のコードで使用しないでください。attacksに公開されています。
はここでコピーpaste'd from pydoc of sqlite3:あなたが必要な場合は
# 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))
DB-APIの実装の中には、実際には変数に%sを使用しています。特に、PostgreSQLの場合はpsycopg2です。これは%sを文字列置換のための%演算子とともに使用すると混乱することはありません(簡単ですが)。 移植性のために、DB-APIのSQLパラメータを指定するための標準的な定義方法があればいいと思います。 – ThatAintWorking
興味深い、それはVARSで別々の代わりに、配列で仕事ない理由(var1、var2、var3)? – Andomar
DB APIの仕様によれば、どちらの方法でも可能です:http://www.python.org/dev/peps/pep-0249/ –
http://docs.python.org/2/library/ sqlite3.html#エスケープ – earthmeLon