1. ホーム
  2. python

SQLiteのパラメータ置換問題

2023-10-09 20:13:52

質問

Python 2.5でSQLite3を使用して、リストを反復処理し、項目の名前に基づいてデータベースから項目の重さを引き出そうとしています。

SQLインジェクションを防ぐために提案された"?" パラメータ置換を使おうとしましたが、うまくいきません。たとえば、私が使用するとき。

for item in self.inventory_names:
    self.cursor.execute("SELECT weight FROM Equipment WHERE name = ?", item)
    self.cursor.close()

エラーが出ます。

sqlite3.ProgrammingError: 提供されたバインディングの数が正しくありません。現在の文は1を使用していますが、8が供給されています。

これはデータベースの初期作成に何らかの原因があると思います。実際にDBを作成する私が作ったモジュールでは、8つのバインディングがあります。

cursor.execute("""CREATE TABLE Equipment 
    (id INTEGER PRIMARY KEY, 
    name TEXT,
    price INTEGER, 
    weight REAL, 
    info TEXT, 
    ammo_cap INTEGER, 
    availability_west TEXT,
    availability_east TEXT)""")

しかし、各項目名に安全性の低い "%s" という置換を使用すると、うまく動作するのです。このように。

for item in self.inventory_names:
    self.cursor.execute("SELECT weight FROM Equipment WHERE name = '%s'" % item)
    self.cursor.close()

1つしか呼び出していないのに、なぜ8つのバインディングがあると思われるのかがわかりません。どうすれば直るのでしょうか?

どのように解決するのですか?

この Cursor.execute() メソッドは、2番目のパラメータとしてシーケンスを期待します。あなたはたまたま8文字の文字列を与えています。

代わりに以下の形式を使用します。

self.cursor.execute("SELECT weight FROM Equipment WHERE name = ?", [item])

Python ライブラリリファレンス: sqlite3 カーソルオブジェクト .