2

重複の可能性:
Pythonの挑戦的な文字列エンコーディング

ティッカーのリストをSQLクエリに入れようとしています。私はPythonを初めて使用します。

cusは、['x'、'y'、...、'a']として設定されたリストです。

test = psql.frame_query(
    "select * from dataBase where cus IN (%r)", con = db) % cus

これを試してみましたが失敗しました。

次の試みは、角かっこを削除してからリストを貼り付けることでした。角かっこを削除して次のようにするにはどうすればよいですか。

cus2 = 'x', 'y', ..., 'a'

私がやろうとしていた:

str = "select * from dataBase where cus IN (%r)" % cus2
test2 = psql.frame_query(str, con = db)

または、これを試みる別の方法はありますか?

ありがとうございました。

4

1 に答える 1

3

SQLでは、クエリに値を挿入するだけでは避けたいと考えています。通常、これはデータベースアダプタに任せます。データベースアダプタは、値から危険なSQLを作成しないようにする方法に関する専門知識を持っています(SQL引用符のエスケープ、別名SQLインジェクション攻撃)。

残念ながら、pandas.io.sqlモジュールには中途半端に実装されたパラメータサポートしかありません。

を使用する代わりに、直接frame_query使用してください。DataFrame.from_records()

まず、パラメータを使用してSQLクエリを生成します。SQLパラメーターの形式は、データベースアダプターごとに異なります。これは、PythonDBAPI標準でいくつかのバリエーションが許可されているためです。ここでは、位置パラメータに使用するMySQLを使用しており%s、Pythonの構文を反映していると仮定します。

sql = "select * from dataBase where cus IN ({0})".format(', '.join(['%s'] * len(cus2)))

これにより、の値ごとに十分なパラメータが作成されますcus2。次に、データベースにクエリを実行します。

cur = psql.execute(sql, con, params=cus2)
rows = cur.fetchall()
columns = [col_desc[0] for col_desc in cur.description]
cur.close()

result = DataFrame.from_records(rows, columns=columns, coerce_float=True)

Sybase接続にモジュールモジュールを使用しているように見えるため、ライブラリが使用する(やや非標準の)SQLパラメータ構文に合わせてこれを調整する必要があります。次の形式を使用する名前付きパラメーターのみを受け入れます@name

params = dict(('@param{0}'.format(i), v) for i, v in enumerate(cus2))
sql = "select * from dataBase where cus IN ({0})".format(
    ', '.join(sorted(params.keys())))

cur = psql.execute(sql, con, params=params)
rows = cur.fetchall()
columns = [col_desc[0] for col_desc in cur.description]
cur.close()

result = DataFrame.from_records(rows, columns=columns, coerce_float=True)
于 2012-12-18T16:38:37.783 に答える