Python MySQLデータベース操作その2(更新、トランザクション) mysqlclientモジュール
2018/07/12
2020/03/26
タグ: mysqlclient, Python, SQLインジェクション, トランザクション
今回はアップデート処理を行いトランザクション処理としてロールバック機能等を入れてみる。ついでにSQLインジェクション対策のパラメータ挿入の仕方で記述します。パラメータの入れ方は多くの人がハマってしまうPython特有のぶら下がりカンマをあえて使います。入れる型に合わせて記述を考慮しなければいけませんがPython独特な書き方だと中々気づきにくいものです。他の言語では複数のリストやarrayを記述する場合は最後のパラメータの後方にはカンマを入れないのですがpythonは必要となるケースがありますのでご注意ください。尚、予め「pip install MySQL-python」or「pip install pymysql」でインストールしてください。mysql driverはpip側のアップデートで名前が変わったりすることもあります。また互換性のあるdriverであれば何でも良いと思いますのでpip searchで調べてみてください。
更新、トランザクション処理を入れたプログラム。SQLインジェクション対策の書き方にもなっている。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
import yaml import MySQLdb def config_db(): with open("db.yaml", "r+") as file: config_set = yaml.load(file) return config_set def db_connect(data,db_name): item = data[db_name] dret = MySQLdb.connect( user = item['user'], passwd = item['password'], host = item['host'], db = item['dbname'], charset = item['charset']) return dret cons = db_connect(config_db(),'DB1') cur = cons.cursor() sql = "select * from users" cur.execute(sql) record = cur.fetchone() while record != None: print(record) record = cur.fetchone() print('----------------------------') pass_data='5555999' try: #通常よくあるケースははフォーマット文とパラメータを"%"で区切るがそれだとSQLインジェクションになる。 #下記の様に型書式だけでOK。内部でSQLインジェクション対策してくれる。 sql = "update users set passwd=%s where name='宮田望'" #挿入パラメータが1つの場合でもタプル形式なので、pass_data後方にぶら下げカンマ入れること。皆ハマるポイントです。複数だと動作し、シングルだとエラーになる。 cur.execute(sql,(pass_data,)) cons.commit() sql = "select * from users" cur.execute(sql) record = cur.fetchone() while record != None: print(record) record = cur.fetchone() except MySQLdb.Error as e: cons.rollback() print("MySQL Database Error: ",e) cons.close() |
更新前と更新後を実行
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
root@LaserBeam5:~/database# python3.6 testc.py (1, '田中広輔', 'Desgw110', 1) (3, '島田大智', '123456', 1) (4, '中村美紀子', '123456', 1) (7, '高田延彦', 'Test231', 1) (10, '音無典子', '12345678', 0) (17, '宮田望', '5555888', 1) ---------------------------- (1, '田中広輔', 'Desgw110', 1) (3, '島田大智', '123456', 1) (4, '中村美紀子', '123456', 1) (7, '高田延彦', 'Test231', 1) (10, '音無典子', '12345678', 0) (17, '宮田望', '5555999', 1) root@LaserBeam5:~/database# |