web-dev-qa-db-ja.com

psycopg2 TypeError:文字列のフォーマット中にすべての引数が変換されるわけではありません

単純なクエリを実行しようとしていますが、パラメーターをどのように渡してもこのエラーが発生します。

これがクエリです(私はTrac dbオブジェクトを使用してDBに接続しています):

cursor.execute("""SELECT name FROM "%s".customer WHERE firm_id='%s'""" % (schema, each['id']))

schemaとeach ['id']はどちらも単純な文字列です

print("""SELECT name FROM "%s".customer WHERE firm_id='%s'""" % (schema, each['id']))

結果:SELECT name FROM "Planing".customer WHERE firm_id='135'

エラーにはfirm_id=の後に引用符を削除するというものがありますが、その方法ではパラメーターは整数として扱われ、::textはまったく同じエラーを引き起こします。

16
konart

データベースクエリで変数を渡すために文字列補間を使用しないでください。ただし、文字列補間を使用してテーブル名を設定することは問題ありません(外部入力ではないか、許可されている値を制限している場合)。試してください:

cursor.execute("""SELECT name FROM %s.customer WHERE firm_id=%%s""" % schema, each['id'])

DB APIの使用に関する規則 は、データベースに対するプログラミングのガイダンスを提供します。

6
RjOllos

私の場合、タプルをcursor.executeに渡す必要があることに気づきませんでした。私はこれを持っていました:

cursor.execute(query, (id))

しかし、代わりにタプルを渡す必要がありました

cursor.execute(query, (id,))
35
Spencer Sutton

私はこれと同じエラーが発生し、私の人生の中で修正方法を見つけることができませんでした。結局、タプルの要素の数に一致する十分なパラメーターがなかったため、それは私の愚かな間違いでした。

con.execute("INSERT INTO table VALUES (%s,%s,%s,%s,%s)",(1,2,3,4,5,6))

テーブルに挿入される値には5つの要素がありますが、タプルには6つの要素があることに注意してください。

12
rsacc

SQLコマンドで変数を渡す正しい方法は、execute()メソッドの2番目の引数を使用することです。そして、私はあなたが2番目のパラメータから一重引用符を削除する必要があると思います、それについてここで読んでください- http://initd.org/psycopg/docs/usage.html#the-problem-with-the-query-parameters =。

テーブル名をパラメーターとしてexecuteに渡すことはできません。これは悪い習慣と見なされますが、いくつかの回避策があります。
psycopg2のパラメーターとしてテーブル名を渡す
SQLクエリパラメータを指定したpsycopg2 cursor.execute()により構文エラーが発生します

テーブル名を渡すにはこれを試してください:

cursor.execute("""SELECT name FROM "%s".customer WHERE firm_id=%s""" % (schema, '%s'), (each['id'],))
3
ndpu

AsIsを使用

from psycopg2.extensions import AsIs

cursor.execute("""
    select name 
    from %s.customer 
    where firm_id = %s
    """, 
    (AsIs(schema), each['id'])
)
2
Clodoaldo Neto