まず前提として、SQL文を文字連結で動的に組み立てることはSQLインジェクションという攻撃を許してしまう可能性(脆弱性)があるので、原則行ってはいけません。
"値" だけが変わる場合は固定の構文にプリペアドステートメントで値を渡せばよいのですが、今回のように構文も変化する場合は、構文を動的に組み立てる必要がでてきます。そもそも論を言うと可能な限りそういった実装は避けるべきです。複合検索など、どうしても条件が変化してしまうような複雑なクエリを実行する場合はクエリビルダーやORマッパーなどのライブラリを使った方が安全かつ便利です。
では実際に構文の動的生成 および プリペアドステートメントに渡すリストの生成 の2つを行うサンプルを示します。
辞書からキーを取り出すには 辞書オブジェクト.keys()
、値を取り出すには 辞書オブジェクト.values()
メソッドを使います。するとキーまたは値がリストとして返ってきます。
さらにリストの各要素を連結して1つの文字列にするには、join() 関数を使います。少々構文が特殊で
結合文字.join(結合するリスト)
と書きます。
python
1dic = {'DATE' : '2014/01/01', 'VALUE' : '100'}
2
3statement = ''.join([
4 'INSERT INTO `TABLE` (',
5 ', '.join('`' + k + '`' for k in dic.keys()),
6 ') VALUES (',
7 ', '.join(['%s'] * len(dic)),
8 ')'])
9
10values = dic.values()
11
12print(statement) # プリペアドステートメントの構文
13# → INSERT INTO `TABLE` (`VALUE`, `DATE`) VALUES (%s, %s)
14print(values) # プリペアドステートメントに渡すリスト
15# → ['100', '2014/01/01']
'`' + k + '`' for k in dic.keys()
の部分は内包表記というテクニックを使っています。Python ではよく使う方法なのでぜひ覚えてください。参考:Pythonの内包表記の使い方まとめ - Life with Python
と、このようにコードがゴッチャゴチャになりますし、キー名にユーザーからの入力値を使った場合、結局SQLインジェクションが行えてしまいます。ですので、やはりライブラリを使うのが適切だと思います。