Python2系で拵えた「踏み台からMySQLをあれこれするプロセス」を3系へ移行してみた
先日「Python2系のサポート期限に備えておきたい事をおさらいしてみる」というエントリーを書きましたが、更に以前書いたエントリー「手作業になりやすい「踏み台サーバ経由でMySQLを実行するプロセス」をコードで完結させてみた」が2系での実装だったことを思い出しました。
Python3系前提で安定して踏み台サーバ経由でMySQLをあれこれしてみるために、依存するライブラリを変更してみました。
利用するアダプタ
今回利用するアダプタはmysqlclient
です。前回の2系環境にて利用したMySQL-Python
をForkしたライブラリであり、恐らく検証コストが低いであろうという1点が理由です。
インストール
pipenvで3系の環境にしておきます。
% pipenv install --python 3.6 % pipenv install mysqlclient sshtunnel % pipenv shell
実装
実行時のコマンドは2系での実装と同じです。
% python main.py
main.py
#!/usr/bin/env python # -*- coding: utf-8 -*- import MySQLdb import csv import sshtunnel import configparser db_conf = {} config = configparser.ConfigParser() config.read('db.ini') db_conf.update(config['default']) def get_conf(): return { 'host': db_conf['host'], 'port': 3306, 'user': db_conf['user'], 'passwd': db_conf['passwd'], 'db': db_conf['db'], 'charset': 'utf8', } def dump_to_csv(): column_names = ["title", "id", "name", "description"] sql = " ".join(["SELECT", ",".join(column_names), "FROM example"]) db_conf = get_conf() with open("dump.csv", "w") as csvfile: csv_writer = csv.writer(csvfile) csv_writer.writerow(column_names) try: print("SSH Tunnel Start") server = sshtunnel.SSHTunnelForwarder( ("XX.XX.XX.XX", 22), #踏み台IP ssh_username="ec2-user", ssh_pkey="~/.ssh/server.pem", local_bind_address=('127.0.0.1', 3306), remote_bind_address=(db_conf["host"], 3306) ) server.start() print("SSH Tunnel Started") print("MySQL Make Connect") db_conf["host"] = '127.0.0.1' cnn = MySQLdb.connectG(**db_conf) cur = cnn.cursor() print("MySQL Maked Connect") print("SQL executing") cur.execute(sql) result = cur.fetchall() print("SQL executed") for row in result: csv_writer.writerow(row) cur.close() cnn.close() server.stop() print("SSH Tunnel Stoped") except Exception as e: print(e) return if __name__ == "__main__": dump_to_csv()
db.ini
[default] user = xxxx passwd = xxxx host = xxxxxxxxxxxxxxxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com db = database
変更点
MySQLdb自体は導入するライブラリを変えただけで、コード上に変更はありませんでした。ただ、3系には存在しない実装として発生するエラーがありました。手直しした箇所は以下の通りです。
execfileをconfigparserに
Python2系に存在したexecfileはPython3系に存在しません。execによる代用方法にて検証してみましたが、シンプルにconfigpaerserによる取り込みへ変更しました。
また、併せてdb.confをdb.iniにして、ファイル内容もini構成へ変更しています。
open時にbyteフラグを省いた
Python2系ではbyteフラグを指定してもstr型で書き出せていたのですが、3系環境ではエラーとなっていたため省きました。
CSV出力時にそのまま渡した
unicodeでの変換時にエラーが発生しており、文字エンコード対処そのものを省きました。
まとめ
幾つかの修正箇所が発生したものの、Python3系の環境でも問題なく動作できることを確認しました。実際に2系から3系へと移植する際の参考になれば幸いです。