【Python】mysqlクエリのWHERE INに配列(list)を直接渡す方法【mysql.connetor】

Pythonはつい最近始めたばかりです。
だからこそ新しい学びが多いですね。

今回はMySQLクエリの動的な作り方について

端的に書くとこのような状況です

  • mysql.connectorをMySQL操作に使用
  • WHERE IN句に配列を渡したい
  • プリペアードステートメントを使って

こういう場面は多いかもしれない

その方法がようやく理解できたので、
同じような人のために記録に残しておきます。

WHERE IN句に配列(list)を展開して渡したかった

例えばこのようなテーブルがあるとします。

▼ 説明用にusersテーブルを作る

▼ 適当にデータを挿入する

▼ こういうデータができる

user_id name
1 Tom
Mike
Luna
Olivia
John
Emma

普通にテーブルを作ってレコード挿入しただけ。

ここまでは問題ないです。

問題はmysql.connectorからSQLを実行した時

問題はPythonのmysql.connetorでコードを書いたときです。

▼ 例えばこういうコードの場合

もし user_ids  がコード的に固定であったり、外部入力を受け取らないなら許容できるかもしれません。それなら変な値が入り込む余地は少ないからです。

でも可変であるならSQLインジェクションの対象になります。外部からデータを受け取って動的にクエリを組み立てているなら尚更ですね。

基本はプリペアードステートメントを使うべき

mysql.connectorでWHERE IN句にlistを直接渡すコード例

では具体的にlistを展開して渡す方法について

先ほどの例だと次のコードで実現できます。

▼ listを動的にクエリに渡すコード例

まず ','.join(['%s'] * len(user_ids))  によって配列の長さ分だけプレースホルダを用意します。この例だと '%s,%s,%s'  みたいな文字列です。(ユーザーIDの個数が3つの場合)

あとはプリペアードステートメントを実行する際に stmt % stmt_formats  として実行クエリ内の %s  を stmt_formats  に置換し、さらにタプル化したユーザーIDを変数として渡してるだけです。

ちょっと説明が難しい…

でもコードを辿れば理解できるはずです。

ここで紹介した方法を使う方が安全なのは間違いない

SQLインジェクションは可変値でのクエリ組み立てで起こります。

mysql.connectorでもプリペアードステートメントは使えるけど…

こういう特殊な場面でも少しだけ工夫が必要ですね。

あと参考として次のPython・MySQL関連記事も紹介します。

▼ Pythonでダウンロードなしでファイルサイズを調べる方法

▼ WHERE IN に指定した順番でレコード取得する方法

以上、Pyhtonのmysqlクエリに配列を渡す方法でした。

もし間違いがあれば教えてください。ではまた (@^^)/~~~

Shareこの記事をシェアしよう!

Commentsこの記事についたコメント

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

CAPTCHA


このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください