今日は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()
