web-dev-qa-db-ja.com

Python SQLワイルドカードとLIKEを使用した文字列形式

pythonでSQLを取得してMySQLdbを正しく処理するのに苦労しています。Pythonの文字列フォーマットが私を殺しています。

私のSQLステートメントはワイルドカードでLIKEキーワードを使用しています。私はPythonでさまざまなことを試しました。問題は、そのうちの1つが機能するようになると、MySQLdbに文字列形式でげっぷするコード行があることです。

試行1:

"SELECT tag.userId、count(user.id)as totalRows FROM user INNER JOIN tag ON user.id = tag.userId WHERE user.username LIKE '%% s%'"%(クエリ)

これはダメです。値エラーが発生します:

ValueError:インデックス128でサポートされていないフォーマット文字 '' '(0x27)

試行2:

"SELECT tag.userId、count(user.id)as totalRows FROM user INNER JOIN tag ON user.id = tag.userId WHERE user.username LIKE '\ %% s \%'"%(クエリ)

試行1でも同じ結果が得られます。

試行3:

like = "LIKE '%" + str(query)+ "%'" totalq = "SELECT tag.userId、count(user.id)as totalRows FROM user INNER JOIN tag ON user.id = tag.userId WHERE user.username "+いいね

これにより、totalq変数が正しく作成されますが、クエリを実行しようとすると、MySQLdbからエラーが発生します。

ファイル "build/bdist.macosx-10.6-universal/Egg/MySQLdb/cursors.py"、行158、execute query = query%db.literal(args)TypeError:フォーマット文字列に十分な引数がありません

試行4:

like = "LIKE '\%" + str(query)+ "\%'" totalq = "SELECT tag.userId、count(user.id)as totalRows FROM user INNER JOIN tag ON user.id = tag.userId WHERE user .username "+ like

これは、試行3と同じ出力です。

これはすべて本当に奇妙に思えます。 PythonのSQLステートメントでワイルドカードを使用するにはどうすればよいですか?

22
gngrwzrd

文字列のフォーマットではありませんが、問題は、Python( PEP 249 )のデータベース操作要件に従ってクエリを実行する方法です。

次のようなものを試してください。

sql = "SELECT column FROM table WHERE col1=%s AND col2=%s" 
params = (col1_value, col2_value)
cursor.execute(sql, params)

psycog2の例をいくつか示します mysqlにも有効な説明がいくつかあります(mysqldbはPEP249 dba apiガイダンス2.0にも準拠しています: mysqldbの例を示します

11
dzida

これらのクエリはすべて、SQLインジェクション攻撃に対して脆弱であるように見えます。

代わりに次のようなものを試してください。

_curs.execute("""SELECT tag.userId, count(user.id) as totalRows 
                  FROM user 
            INNER JOIN tag ON user.id = tag.userId 
                 WHERE user.username LIKE %s""", ('%' + query + '%',))
_

execute()に渡される2つの引数がある場合。

Python文字列フォーマット式でアンパサンドをエスケープするには、アンパサンドを2倍にします。

'%%%s%%' % search_string

編集:しかし、私は間違いなく別の答えに同意します。 SQLクエリでの直接の文字列置換は、ほとんどの場合、悪い考えです。

10
jrdioko

次のように2倍にすることで、パーセンテージ文字をエスケープしてみることができます。

query_to_get_user_name = """ 
SELECT tag.userId, count(user.id) as totalRows FROM user INNER JOIN tag 
ON user.id = tag.userId 
WHERE user.username LIKE '%%%s%%' """ % (user_name,) 

cursor.execute(query_to_get_user_name)
0
shreesh katti