今日はPython3でMySQLに接続する方法についてです。
ドライバーについて
Python3でMySQLに接続するドライバーは決め手がない、と言われていますが、当サイトではmysqlclientをおすすめします。これはPython2系でよく利用されていたMySQLdbからフォークされたものです。
mysqlclientのインストールはpipで可能です。linux環境では事前に以下のライブラリをインストール必要があります。
# debian系 sudo apt-get install python-dev default-libmysqlclient-dev sudo apt-get install python3-dev # rhel系 sudo yum install python-devel mysql-devel sudo yum install python3-devel
pipは以下の通りです。
pip install mysqlclient
接続及びSELECT文の実行
早速接続してクエリを投げてみましょう。MySQLdbをインポートし、MySQLdb.connectで接続が可能となります。引数でユーザ、パスワード、DBホスト、DB、文字コードを指定することができます。
[接続 & selectサンプル]
import MySQLdb def db_sample(): """ 接続サンプル """ # 接続する con = MySQLdb.connect( user='db user', passwd='db password', host='localhost', db='sample', charset="utf8") # カーソルを取得する cur= con.cursor() # クエリを実行する sql = "select id, body, post_code, created from posts" cur.execute(sql) # 実行結果をすべて取得する rows = cur.fetchall() # 一行ずつ表示する for row in rows: print(row) cur.close() con.close() if __name__ == "__main__": db_sample()
カーソルに対し、fetchallを利用すると、行がすべて取得できます。rowはタプル形式です。以下のような形で出力されます。
[実行結果]
(1, 'aaaaaaaaaa', 1, '2016-10-16 22:51:55')
(2, 'bbbbbbbbbb', 1, '2016-10-16 22:52:03')
(3, 'cccccccccc', 1, '2016-10-16 22:52:06')
(4, 'dddddddddd', 2, '2016-10-16 22:52:11')
(5, 'eeeeeeeeee', 2, '2016-10-16 22:52:17')
先頭の一行だけ取得したい場合は以下のように、fetchoneを利用します。
row = cur.fetchone()
SQL実行時にパラメータを指定する
では次に、SQLにパラメーターを渡してみましょう。
import MySQLdb def db_sample(): """ 接続サンプル """ # 接続する con = MySQLdb.connect( user='db user', passwd='db password', host='localhost', db='sample', charset="utf8") # カーソルを取得する cur= con.cursor() # クエリを実行する sql = "select id, body, post_code, created from posts where id > %s and post_code in %s" cur.execute(sql, (1, [1, 2, 3], )) # 実行結果をすべて取得する rows = cur.fetchall() # 一行ずつ表示する for row in rows: print(row) cur.close() con.close() if __name__ == "__main__": db_sample()
SQL内でパラメータにしたい箇所は%sにし、cur.executeの第2引数にパラメータをタプルで指定します。in句の場合、リストが利用できます。
更新系
最後に更新系の処理です。といっても、select文と同様、executeメソッドでsqlを実行すればOKです。
import MySQLdb def db_sample(): """ 接続サンプル """ # 接続する con = MySQLdb.connect( user='db user', passwd='db password', host='localhost', db='sample', charset="utf8") # カーソルを取得する cur= con.cursor() # 更新系SQLを実行する # insert insert_sql = "insert into `sample`.`posts` (`body`, `post_code`, `created`) VALUES (%s, %s, now());" cur.execute(insert_sql, ("body text" , 3, )) update_sql = "update `sample`.`posts` SET `post_code`='3' WHERE `id`=%s;" cur.execute(update_sql, (6, )) delete_sql = "delete from `sample`.`posts` where id = %s;" cur.execute(delete_sql, (6, )) cur.close() con.close() if __name__ == "__main__": db_sample()