🐍

Python3 mysql connector

2020/09/27に公開

Python3で MySQLに繋ぐ方法を説明するページです。
https://ktykogm.hatenablog.com/entry/2019/05/19/231008 のクロス投稿になります。

準備

pip install mysql-connector-python

or

pip3 install mysql-connector-python

[注意] mysql-connector-python-rf は更新が止まっていたので使わないようにします。

Sample code / snippet

注意!!!

" " で囲むとPassword Errorが発生して駄目です。
シングルクォートのみ対応しています。

超シンプル版

#!/usr/bin/env python

import mysql.connector

if __name__ == '__main__':
        cnx = mysql.connector.connect(
                user='root',
                host='localhost',
                password='XXXXXX',# ダブルクォートで囲っては駄目
                database='XXXXXX'
        )
        cnx.close()

超シンプルfile指定版

例えば、 ${HOME}/.my.cnf を使う場合

import mysql.connector
import os

if __name__ == '__main__':
        home = os.environ.get("HOME")
        cnx = mysql.connector.connect(option_files=home + '/.my.cnf')
        cnx.close()

通常版

<table_name> に指定したtableに対して、DESCコマンド (e.g. DESC example_table;)を使う例です。

#!/usr/bin/env python

import mysql.connector

def get_description_table(table):
    db_cursor = db_conn.cursor()
    sql = "DESC "+ table
    db_cursor.execute(sql)
    #desc_table = db_cursor.fetchone()
    desc_table = db_cursor.fetchall()
    db_conn.close()
    return desc_table

def create_db_connection():
    global db_conn
    db_conn = mysql.connector.connect(
        user='XXXX',
        password='XXXX',
        database='XXXX',
        port=3306
    )

if __name__ == '__main__':
    print("DB test connect is started....")
    create_db_connection()
    print(get_description_table("<table_name>"))

本番用の例

実際に使いやすくするにはOptionで指定できたり、fileで指定できたり、Security面も気にした方が良いと思います。
その場合の例は以下になります。

#!/usr/bin/env python
import argparse
import mysql.connector

def read_env_variables():
    global args
    parser = argparse.ArgumentParser(description="read arguments")
    parser.add_argument("--HOST", type=str, help="HOST name", required=True)
    parser.add_argument("--USER", type=str, required=False, help="It is recommended not to use this. You can use MySQL conf.")
    parser.add_argument("--PASS", type=str, required=False, help="It is recommended not to use this. You can use your MySQL conf.")
    parser.add_argument("--CONF", type=str, required=False, default=os.environ.get("HOME") + "/.my.cnf", help="Default is ${HOME}/.my.cnf")
    parser.add_argument("--DATABASE", type=str, required=True)
    parser.add_argument("--PORT", type=int, required=False)
    args = parser.parse_args()
    print(args)

def get_description_table(table):
    db_cursor = db_conn.cursor()
    sql = "DESC "+ table
    db_cursor.execute(sql)
    #desc_table = db_cursor.fetchone()
    desc_table = db_cursor.fetchall()
    db_conn.close()
    return desc_table

def create_db_connection():
    global db_conn
    db_conn = mysql.connector.connect(
        host=args.HOST,
        user=args.USER,
        passwd=args.PASS,
        database=args.DATABASE,
        port=args.PORT,
        option_files=args.CONF
    )


if __name__ == '__main__':
    read_env_variables()
    print("DB test connect is started....")
    create_db_connection()
    print(get_description_table("<table_name>"))

こんな感じです。

${HOME}/.my.cnf を使う場合は例えば以下のように設定しておきます。

[client]
user = xxxx
password = xxxx
# .. 省略

実行例

command.py --HOST=server1  --DATABASE=db
command.py --HOST=server1 --CONF=${HOME}/.tmp_my.cnf --DATABASE=db --PORT=13306
command.py --HOST=server1 --USER=ktykogm --PASSWORD=xxxxx --DATABASE=db

説明

    parser.add_argument("--USER", type=str, required=False, help="It is recommended not to use this. You can use MySQL conf.")
    parser.add_argument("--PASS", type=str, required=False, help="It is recommended not to use this. You can use your MySQL conf.")

    parser.add_argument("--CONF", type=str, required=False, default=os.environ.get("HOME") + "/.my.cnf", help="Default is ${HOME}/.my.cnf")

#...
        user=args.USER,
        passwd=args.PASS,
        #...
        option_files=args.CONF

の部分は、
コマンド実行時やpsコマンドの標準出力にPasswordを表示させないようにするためにも、上記のように ${HOME}/my.cnf がデフォルトで指定されるようにしています。
(例えば、コマンド引数に環境変数を渡すだけだと表示されてしまいます。)
ただし、使用しなくなったら ~/.my.cnf の削除はお忘れなく。

Discussion