このようなパラメータ化されたステートメントは、値で使用することを意図していると思います。 テーブル名(またはSQLキーワードなど)ではありません。ですから、基本的にこれでは運が悪いのです。
ただし、このメカニズムはSQLインジェクションを防ぐことを目的としており、通常はコード作成時にアクセスするテーブルがわかっているため、誰かが悪意のあるコードをインジェクションする可能性はほとんどありません。先に進んで、文字列にテーブルを書き込んでください。
何らかの(おそらくひねくれた)理由で、テーブル名を次のようにパラメトリックに保つ場合:
- テーブル名がプログラム(辞書やクラス属性など)に由来する場合は、通常の文字列置換を行います。
- テーブル名が外部からのものである場合(「ユーザー入力」と考えてください):そうしないか、ユーザーを完全に信頼して前のアプローチ1を適用します。
例:
cursor.execute(
'SELECT * FROM %s where %s = %s'
% ("my_table", "colum_name", "%s"), #1
("'some;perverse'string;--drop table foobar")) #2
#1
:この時点で3番目の%sを別の'%s'に置き換えて、後でpsycopg2 #2
で処理できるようにします。 :これは、psycopg2によって適切に引用され、元の文字列の3番目の「%s」の代わりに配置される文字列です