Psycopg2にパラメータ化されたクエリをPostgreSQLに渡す最良の方法は何ですか?独自のエスケープメカニズムやアダプターを記述したくありません。psycopg2のソースコードと例は、Webブラウザーで読むのが難しいです。
PyGreSQLや別のpython pgアダプタなど)に切り替える必要がある場合、それで十分です。単純なパラメータ化が必要です。
psycopg2
は、DB-API 2.0のルールに従います( PEP-249 で設定)。つまり、execute
オブジェクトからcursor
メソッドを呼び出してpyformat
バインディングスタイルを使用すると、エスケープが行われます。たとえば、次のshouldは安全です(そして機能します)。
cursor.execute("SELECT * FROM student WHERE last_name = %(lname)s",
{"lname": "Robert'); DROP TABLE students;--"})
Psycopgのドキュメントから
( http://initd.org/psycopg/docs/usage.html )
警告決して、決して、決してPython文字列連結(+)または文字列パラメータ補間(%)を使用して、SQLクエリ文字列に変数を渡さないでください。
SQLコマンドで変数を渡す正しい方法は、execute()メソッドの2番目の引数を使用することです。
SQL = "INSERT INTO authors (name) VALUES (%s);" # Note: no quotes
data = ("O'Reilly", )
cur.execute(SQL, data) # Note: no % operator
役立つと思われる例をいくつか示します
cursor.execute('SELECT * from table where id = %(some_id)d', {'some_id': 1234})
または、フィールド名、値のdictに基づいてクエリを動的に構築できます。
fields = ', '.join(my_dict.keys())
values = ', '.join(['%%(%s)s' % x for x in my_dict])
query = 'INSERT INTO some_table (%s) VALUES (%s)' % (fields, values)
cursor.execute(query, my_dict)
注:フィールドはコードで定義する必要がありますnotユーザー入力。そうしないと、SQLインジェクションの影響を受けやすくなります。