9

sqliteファイルから読み取った文字列をPythonのデータベースに挿入しようとしています。文字列には空白(改行、タブ文字、スペース)があり、一重引用符または二重引用符のように見えます。これが私がそれをやろうとする方法です:

import sqlite3
conn = sqlite3.connect('example.db')
c = conn.cursor()

# Create table
c.execute('''CREATE TABLE test
             (a text, b text)''')

f = open("foo", "w")
f.write("hello\n\'world\'\n")
f.close()

testfield = open("foo").read()

# Insert a row of data
c.execute("INSERT INTO test VALUES ('%s', 'bar')" %(testfield))

# Save (commit) the changes
conn.commit()

私はこれがエラーで失敗することを発見しました:

    c.execute("INSERT INTO test VALUES ('%s', 'bar')" %(testfield))
sqlite3.OperationalError: near "world": syntax error

どうすればこれを達成できますか?データベースに挿入する前に文字列をエスケープする必要がありますか?エスケープする場合はどうすればよいですか?ありがとう。

4

1 に答える 1

25

文字列フォーマットの代わりに SQL パラメータを使用します。

c.execute("INSERT INTO test VALUES (?, 'bar')", (testfield,))

SQL パラメータを使用する場合は、データベース ライブラリに引用を処理させます。さらに良いことに、データベースにクエリを最適化し、最適化されたクエリ プランを再利用して、同じ基本クエリを (異なるパラメータで) 複数回実行します。

最後になりましたが、SQL に似た危険な値を回避する方法をデータベース ライブラリが最もよく知っているため、SQL インジェクション攻撃に対する防御が大幅に強化されます。

sqlite3 のドキュメントを引用するには:

通常、SQL 操作では Python 変数の値を使用する必要があります。安全ではないため、Python の文字列操作を使用してクエリを組み立てるべきではありません。これにより、プログラムが SQL インジェクション攻撃に対して脆弱になります (問題が発生する可能性のあるユーモラスな例については、http: //xkcd.com/327/を参照してください)。

代わりに、DB-API のパラメーター置換を使用してください。値を使用する場所にプレースホルダーとして配置し、カーソルのメソッド?の 2 番目の引数として値のタプルを指定します。execute()

于 2013-02-04T20:36:20.550 に答える