お茶漬けびより

"あなたに教わったことを、噛んでいるのですよ" 五等分の花嫁 7巻 「最後の試験が五月の場合」より

Python 3.6 で MySQL データベースに接続

f:id:pickles-ochazuke:20171209164122j:plain

お久しぶりです。 9月に就職が決定して、そこから空いた一週間で北の方を旅行して、仕事が始まって最初の一ヶ月は給料なくて、11月に初というか3,4ヶ月ぶりの給料でなんとか生活を凌いでいます。
前の仕事は、C言語だったんですけど、今の場所はすることによって言語が変わるそうで、今は Python をメインに触っています。あと初めて SQL を仕事で使っていまして、知らないことだらけで初めてコンピュータサイエンスを学んだ時のようで楽しいです。

さて、今月はなるべく更新をしたいなと思っていますので、小さい内容でも更新していきたいと思っています。主に仕事で学んだことをまとめる方向にしたいので、PythonSQL の話になるかなーと。

では、本題です。 以下を参考にしています。

qiita.com

環境構築

Python のバージョンは、3.6.3 です。 バージョンの確認は、コマンドプロンプトpython --version を実行すれば確認できます。できなければ、パスが通ってないので、通しましょう。

まずは、必要なパッケージをインストールします。

pip install mysql-connector-python-rf

会社の環境だとプロキシの問題で、pip が上手くインストールしてくれないんですよね。そこら辺も覚えている範囲でまとめたい……。

mysql-connector-python も必要っぽいので、以下から落としてきます。
https://pypi.python.org/pypi/mysql-connector-python
こだわりがなければ最新のやつを落としてください。私は、mysql-connector-python-8.0.5.tar.gz を落としました。
落としたファイルの場所でコマンドプロンプトを開いて、以下を実行します。

pip install mysql-connector-python-8.0.5.tar.gz

そしたらインストールが成功するはずです。しなければ管理者権限でコマンドプロンプトを開いて、実行してみてください。 終わったら、pip list で出力されたパッケージリストに今入れた二つがあるか確認します。

MySQL をインストールしていなければ、インストールしましょう。ここでは、その説明は除きます。MySQL サーバを立ち上げて、データベースとテーブルを作成して、準備完了です。

MySQL データベース(DB)への接続

まずは、接続です。各引数は、自身の環境に合わせて変えてください。

import mysql.connector

conn = mysql.connector.connect(
    host = 'localhost',
    port = 3306,
    user = 'root',
    password = 'pass',
    database = 'test',
)

とくにエラーが発生しなければ成功しているはずです。この conn を使って、データベースに対していろいろ操作します。次に、接続が可能か調べるためには、以下を実行します。

connected = conn.is_connected()
print(connected)
if (not connected):
    conn.ping(True)

conn.is_connected() によって接続が可能か真偽値で返ってきます。True の場合は、接続が可能で、False の場合は、接続が不可能な状態です。conn.ping(True) は再接続を試みているのですが、conn.is_connected() が False なら再接続で解決はしなさそうですね……環境に合わせた対処が必要になると思います。

conn.ping(True) は、長い時間接続していると DB との接続が切れることがあるそうなので、その対処のために使うそうです。つまり、定期的に接続して切られないようにしている感じです。

クエリの実行

次にカーソルオブジェクトを作成します。カーソルというのは、データベースで使われる用語のようです。詳しくは知らないので、ここでは、クエリの実行と結果を受け取るために必要な DB への命令方法だと思えば問題ないと思います。

cur = conn.cursor()
cur.execute('select * from member')
table = cur.fetchall()
print(table)

conn.cursor() で、カーソルオブジェクトを作成し、cur.execute() で文字列をクエリとして DB に送ります。その結果を cur.fetchall() で受け取り、print() 出力しています。

ちなみに cur.fetchall() は、例えば SELECT の結果を全て受け取りますが、 cur.fetchone() は結果を一つだけ受け取ります。fetchone() は、何度も実行することで続きのデータを受け取ることができます。

例として、SELECT * FROM Table; というクエリを実行して、レコードが 3 つ現れるとします。fetchall() の場合は、この結果を全て受け取りますが、fetchone() では、レコードを 1 つだけ受け取ります。全て受け取る場合は、3 回実行する必要があるわけです。

それぞれにメリット、デメリットがあるようですがここでは説明しません(というか知りません……)。ちなみに、レコードを全て受け取った状態で fetchone()print() で出力すると None と出力されるので、 for 文などで簡単に回せそうです。

以上が簡単な MySQL データベースへの接続方法です。重要なのは、 mysql.connector.connect(), connect.cursor(), cursor.execute(), cursor.fetchall() ですかね。

最後に一通り実行できるコードを載せておきます。

# -*- coding: utf-8 -*-
import mysql.connector

conn = mysql.connector.connect(
    host = 'localhost',
    port = 3306,
    user = 'root',
    password = 'pass',
    database = 'test',
)

connected = conn.is_connected()
print(connected)
if(not connected):
    conn.ping(True)

cur = conn.cursor()

cur.execute('SELECT * FROM member')

# table = cur.fetchall()
# print(table)

print(cur.statement)
print(cur.fetchone())
print(cur.fetchone())
print(cur.fetchone())
print(cur.fetchone())

参考

今回出てきた API のドキュメントを載せておきます。

MySQL :: MySQL Connector/Python Developer Guide :: 7.1 Connector/Python Connection Arguments

MySQL :: MySQL Connector/Python Developer Guide :: 10.2.25 MySQLConnection.is_connected() Method

MySQL :: MySQL Connector/Python Developer Guide :: 10.2.27 MySQLConnection.ping() Method