LoginSignup
33
37

More than 5 years have passed since last update.

[実装備忘録] Python3のpandasでMySQLにアクセスする方法

Last updated at Posted at 2017-12-25

MySQLパッケージの選択

"pip search mysql" を実行し、どんなMySQL関連パッケージがあるのか調べたら、大量にヒットして収拾が付かない事態になった。
そこで、バージョン番号をチェックし、継続的に保守されているであろうパッケージを絞り込んだ。

$ pip search mysql|grep "(2."
getMysqlConnPara (2.0.0)                                        - Mysql connection parameters defined in a text file, reads the parameter file and return the connection parameter's dict
pg_chameleon (2.0.0rc1)                                         - MySQL to PostgreSQL replica and migration
mysql-latin1-codec (2.0)                                        - Python string codec for MySQL's latin1 encoding
WintxDriver-MySQL (2.0.0-1)                                     - MySQL support for Wintx
WintxDriver-MySQLFabric (2.0.0-1)                               - MySQL Fabric support for Wintx
scrapy-mysql-pipeline (2017.10.10)                              - Asynchronous mysql Scrapy item pipeline
umysql (2.61)                                                   - Ultra fast MySQL driver for Python
cns.recipe.zmysqlda (2.0.9)                                     - Recipe for installing ZMySQLDA
django-cymysql (2.0.0)                                          - Django database backend for cymysql
mysql-connector-python-rf (2.2.2)                               - MySQL driver written in Python
django-mysql (2.2.0)                                            - Extensions to Django for use with MySQL/MariaDB
mysql-connector (2.1.6)                                         - MySQL driver written in Python
HTSQL-MYSQL (2.3.3)                                             - A Database Query Language (MySQL backend)
collective.recipe.zmysqlda (2.0.9)                              - Recipe for installing ZMySQLDA
mysqlpy (2.1.7)                                                 - MySQL driver written in Python

バージョン番号が2.xの域に達しているパッケージのリストを検索で調べていったところ、MySQL公式パッケージ mysql-connector-python-rf がどうも良さそうである。(Python3対応やDBAPI2対応、継続的サポートの安心度などなど)
これをインストールすることにした。

mysql-connector-python-rf のインストール

AWSのEC2インスタンス(CentOS)とローカルクライアント(Windows7)の両方にインストールすることにした。
実際にMySQLサーバーが動いているのはEC2インスタンスであるが、クライアントのPyCharmにもパッケージを認識してもらいたいからである。

CentOSへのインストール

特に難しいことはない。pip でインストールする。

$ pip install mysql-connector-python-rf
    Collecting mysql-connector-python-rf
      Downloading mysql-connector-python-rf-2.2.2.tar.gz (11.9MB)
        100% |????????????????????????????????| 11.9MB 52kB/s
    Building wheels for collected packages: mysql-connector-python-rf
      Running setup.py bdist_wheel for mysql-connector-python-rf ... done
      Stored in directory: /home/*******/.cache/pip/wheels/bb/53/e4/dced82f8a15f96a8afbe626ebb2939d2901b29e610a97fc1ba
    Successfully built mysql-connector-python-rf
    Installing collected packages: mysql-connector-python-rf
    Successfully installed mysql-connector-python-rf-2.2.2

Windows7へのインストール

管理者権限でAnaconda Promptを起動する。(そうしないと権限エラーでインストール処理が途中で止まってしまった)
Python2とPython3が併存する開発環境なので、念のためちゃんとPython3を認識しているか確認。

(C:\ProgramData\Anaconda3) C:\windows\system32>pip -V
pip 9.0.1 from C:\ProgramData\Anaconda3\lib\site-packages (python 3.6)

問題なし。
ということで、pip でインストール。

(C:\ProgramData\Anaconda3) C:\windows\system32>pip install mysql-connector-python-rf
Collecting mysql-connector-python-rf
  Downloading mysql-connector-python-rf-2.2.2.tar.gz (11.9MB)
    100% |████████████████████████████████| 11.9MB 66kB/s
Building wheels for collected packages: mysql-connector-python-rf
  Running setup.py bdist_wheel for mysql-connector-python-rf ... done
  Stored in directory: C:\Users\********\AppData\Local\pip\Cache\wheels\bb\53\e4\dced82f8a15f96a8afbe626ebb2939d2901b29e610a97fc1ba
Successfully built mysql-connector-python-rf
Installing collected packages: mysql-connector-python-rf
Successfully installed mysql-connector-python-rf-2.2.2

無事インストール完了。PyCharmも認識してくれた。

公式ドキュメント

公式ドキュメントは以下から参照できる。
https://dev.mysql.com/doc/connector-python/en/

pandas からMySQLにアクセスする

pandasには、いつもお世話になっている。解析処理は、pandasのデータフレーム抜きには考えられない。ということで、pandasから直接MySQLにアクセスして、データフレームを取ってきてもらう。

pandasのread_sql は、引数con にDBAPI2に対応しているオブジェクトを指定することができる。
https://pandas.pydata.org/pandas-docs/stable/generated/pandas.read_sql.html

先ほどインストールした mysql-connector-python-rf だが、公式サイトを調べると、ちゃんとPython Database API Specification v2.0(PEP 249)に対応しているとあった。つまり、DBAPI2 に対応しているわけである。
https://dev.mysql.com/doc/connector-python/en/connector-python-introduction.html

ということは、pandasのread_sqlで使うことができるだろう。
(余談だが、仕事では Hive の接続インスタンスを指定して、pandas で直接Hiveテーブルを読むことができていたので、当然MySQLでも同じことが出来るはずと考えていた)

MySQL に接続するコード

ささっと、以下のようなクラスを組んだ。

connector/mysql.py
import mysql.connector

class MySQL():
    def __init__(self, config):
        u"""
        :param config: 接続設定を格納した辞書
        """
        self.config = config
        self.conn = None
        if config is not None:
            self.connect()

    def connect(self, config=None):
        u"""
        MySQLに接続する。
        :return:
        """
        if config is None:
            config = self.config
        conn = mysql.connector.connect(**config)
        self.conn = conn
        return conn

connectの引数configは、こんな感じで値をセットする。

config = { 'host' : 'localhost',
           'user' : 'some_user',
           'password' : 'some_password',
           'database' : 'some_database',
           'charset' : 'utf-8' }

上記以外にも引数を指定できる。
詳細は、公式サイトの以下のページを参照。
https://dev.mysql.com/doc/connector-python/en/connector-python-connectargs.html

pandasでMySQLテーブルを読む

MySQLへの接続子インスタンスを生成したら、それを引数に指定して pandasのread_sqlを使う。
するとデータフレームを取得することができる。
サンプルコードはこんな感じ。(以前、自分が作った為替市場の値動きテーブルを読む想定で実装)

sample_mysql.py
import pandas as pd
from connector.mysql import MySQL
config = { 'host' : 'localhost',
           'user' : 'some_user',
           'password' : 'some_password',
           'database' : 'some_database',
           'charset' : 'utf-8' }
mysql = MySQL(config)

# 為替市場の値動きレコードを読むサンプル
sql = """
        SELECT
            *
        FROM
            {table_name}
        WHERE
            code='{code}'
            AND tick_date='{tick_date}'
        ORDER BY tick_datetime
""".format(table_name=table_name, code=market_code, tick_date=tick_date)

# pandas でMySQLテーブルを読む
df_read = pd.read_sql(sql, mysql.conn)
print(df_read.head())

無事に動くと、こんな結果が得られる。

     time_pos  code   tick_date       tick_datetime  tick_minute     open  \
0  1447925580     1  2015-11-19 2015-11-19 18:33:00        66780  123.156
1  1447925640     1  2015-11-19 2015-11-19 18:34:00        66840  123.158
2  1447925700     1  2015-11-19 2015-11-19 18:35:00        66900  123.160
3  1447925760     1  2015-11-19 2015-11-19 18:36:00        66960  123.137
4  1447925820     1  2015-11-19 2015-11-19 18:37:00        67020  123.135

      high      low    close
0  123.164  123.156  123.158
1  123.160  123.140  123.160
2  123.160  123.139  123.139
3  123.140  123.135  123.137
4  123.149  123.135  123.149
33
37
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
33
37