web-dev-qa-db-ja.com

Psycopg2プレースホルダーを使用したテーブルへの挿入

これはかなりばかげた質問かもしれませんが、ここで何が間違っていますか?テーブルを作成しますが、INSERT INTOが機能しません。プレースホルダーで何か間違っているのでしょうか?

conn = psycopg2.connect("dbname=postgres user=postgres")
cur = conn.cursor()
escaped_name = "TOUR_2"
cur.execute('CREATE TABLE %s(id serial PRIMARY KEY, day date, elapsed_time varchar,    net_time varchar, length float, average_speed float, geometry GEOMETRY);' % escaped_name)

cur.execute('INSERT INTO %s (day,elapsed_time, net_time, length, average_speed, geometry) VALUES (%s, %s, %s, %s, %s, %s)', (escaped_name, day ,time_length,  time_length_net, length_km, avg_speed,  myLine_ppy))

conn.commit()
cur.close()
conn.close()

INSERT INTO呼び出しは機能しません。

cur.execute('INSERT INTO %s (day,elapsed_time, net_time, length, average_speed,  
geometry) VALUES (%s, %s, %s, %s, %s, %s)'% (escaped_name, day ,time_length,  
time_length_net, length_km, avg_speed,  myLine_ppy))
psycopg2.ProgrammingError: syntax error at or near ":"
LINE 1: ...h, average_speed, geometry) VALUES (2013/09/01 , 2:56:59, 02...

誰かがこれで私を助けることができますか?本当にありがとう!

17
Timothy Dalton

あなたはPython文字列のフォーマットを使用しており、これは非常に悪い考え(TM)です。SQLインジェクションを考えてください。それを行う正しい方法はバインドされた変数を使用することです:

cur.execute('INSERT INTO %s (day, elapsed_time, net_time, length, average_speed, geometry) VALUES (%s, %s, %s, %s, %s, %s)', (escaped_name, day, time_length, time_length_net, length_km, avg_speed, myLine_ppy))

パラメータのタプルは、execute()の2番目の引数として指定されます。また、値をエスケープする必要はありません。psycopg2がエスケープを行います。この特定のケースでは、テーブル名を変数(escaped_name)に渡さず、クエリ文字列に埋め込むことも推奨されます。psycopg2はテーブル名と列名を引用する方法を知らず、値のみを認識します。

Psycopg2のドキュメントを参照してください。

http://www.psycopg.org/psycopg/docs/usage.html#passing-parameters-to-sql-queries

プログラムでSQLステートメントを生成する場合、通常の方法はPythonステートメントのフォーマットと引数の変数バインディングを使用することです。たとえば、escaped_nameにテーブル名がある場合、行う:

query = "INSERT INTO %s (col1, ...) VALUES (%%s, ...)" % escaped_name
curs.execute(query, args_Tuple)

明らかに、クエリでプレースホルダーを使用するには、最初の形式でバインドされた引数を導入する%を引用符で囲む必要があります。

これは安全であることに注意してくださいif and only ifescaped_nameが外部入力(たとえば、テーブルのベース名とカウンター)を無視してコードによって生成されますが、ユーザーが提供したデータを使用すると、SQLインジェクションのリスクがあります。

29
fog

psycopg2 v2.7これを行うためのサポートされた方法があります: psycopg2.sql docs

2
Matt