質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

2回答

4471閲覧

Pythonで辞書からMySQLのINSERT文を作成する簡単な方法を教えてください

NUEH7hdOSA

総合スコア15

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

1クリップ

投稿2017/07/31 22:42


{'DATE' : '2014/01/01', 'VALUE' : '100'}

"insert into TABLE (DATE, VALUE) VALUES (2014/01/01, 100)"

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

quickquip

2017/07/31 23:47

そのままPythonからデータベースアクセスをするのであれば、そのライブラリを書いた方がいいです。文字列を組み立てるのは「やってはいけない」類のことなので、ライブラリのプレースホルダの機能を使った方法を回答してもらうべきです。
NUEH7hdOSA

2017/08/01 00:07

ご回答ありがとうございます。ライブラリのプレースホルダ機能に関してですが、後ほど新たに質問したいと思います。この質問は辞書-文字列変換のリファレンンスとして残しておきたいと思います。
guest

回答2

0

ベストアンサー

まず前提として、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インジェクションが行えてしまいます。ですので、やはりライブラリを使うのが適切だと思います。

投稿2017/08/01 01:27

編集2017/08/01 01:29
miyahan

総合スコア3095

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

NUEH7hdOSA

2017/08/01 01:45 編集

自己解決してしまいましたが、素晴らしいご回答ありがとうございます。クエリビルダーやORマッパー等のライブラリは初耳です。今後導入を検討してみたいと思います。ありがとうございました。
guest

0

自己解決しました。簡単な話でした。

dict = {'DATE' : '2014/01/01', 'VALUE' : '100'} print( 'insert into TABLE (' + ', '.join([str(k) for k in dict.keys()]) + ') VALUES (' + ', '.join([str(v) for v in dict.values()]) + ')')

投稿2017/08/01 01:25

編集2017/08/01 01:27
NUEH7hdOSA

総合スコア15

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問