例えばweb画面にチェックボックスを用意しておいて、python側でリストに格納した後にIN句に渡したいと。そんな時に。
結論
例
前提
内容には関係はないけど、念のため。
- データベース:wnjpn.db
- テーブル:word
- 条件を絞りたいカラム:pos
“pos”カラムには、’n’、’v’、’a’、’r’ のどれかが格納されている。(どうでもいいけど、n=名詞、v=動詞、a=形容詞、r=副詞)
サンプルコード
どういう動きか
>>> list = ['n','v','a','r'] >>> query = 'SELECT * FROM word WHERE pos IN ({})'.format(', '.join(':{}'.format(i) for i in range(len(list)))) >>> query 'SELECT * FROM word WHERE pos IN (:0, :1, :2, :3)' >>> params = ({str(i): part for i, part in enumerate(list)}) >>> params {'0': 'n', '1': 'v', '2': 'a', '3': 'r'}
こんな感じでリストの要素数分、”:number”を埋め込んでqueryを作成。(query)
execute()で渡す引数のパラメータをタプルで作成。(params)
ちなみにこれでwordnetのDBでSELECTすると
>>> for row in cur.execute(query, params): ... print(row) ... (155288, 'jpn', '頭金', None, 'n') (155289, 'jpn', 'どうにかこうにか', None, 'r') (155290, 'jpn', '大砲', None, 'n') (155291, 'jpn', 'スチーム', None, 'n') (155292, 'jpn', '溢れでる', None, 'v') (155293, 'jpn', 'マーティニ', None, 'n') (155294, 'jpn', '検閲官', None, 'n') (155295, 'jpn', 'シャイラー', None, 'n') (155296, 'jpn', 'イベリア', None, 'n') (155297, 'jpn', '吃逆', None, 'n')
こんな感じになる。と。
その他
「%」を使用してフォーマットするやり方もある。以下は %を使いつつ、”:XXX” の形式ではなくて “?” でqueryを作る。
>>> query = 'SELECT * FROM word WHERE pos IN (%s)' % ','.join('?'*len(list)) >>> query 'SELECT * FROM word WHERE pos IN (?,?,?,?)'
これだと、SQLインジェクション対策ができていないという話を聞いたのだけど、不明。
コメント