LoginSignup
2
4

More than 5 years have passed since last update.

Python2.7でPyMySQLを使用してSQLを実行する

Last updated at Posted at 2017-11-14

今回のお題

一部通知用のデータをとりあえずMySQLに溜め込もうかなと思いますので、
MySQLにSELECTしてみて、結果を取れればと思います。

簡単なテーブルの作成

とりあえずブログを書く人を順番に指名してSlackに通知するが最終目標なので、
仮で下記のような構造のテーブルを作ります。
テーブル名:test

id name target_flag
1 Aさん 1
2 Bさん 1
3 Cさん 1
4 Dさん 0
5 Eさん 1

idはPK、nameは仮の名前、target_flagはこの処理の対象者か否かです(1が対象者)
こちらのテーブルにアクセスし、target_flag=1のデータだけ取得します。

PyMySQLでのアクセスを試してみる

Anaconda(python)からMySQLを使う

こちらを参考にさせていただきました。
書き方は違いますが、やってることが一緒ですね。

mysql.py
# -*- coding: utf-8 -*-
# # モジュール読み込み
import pymysql.cursors

def lambda_handler(event, context):
    # MySQLに接続する
    conn = pymysql.connect(host='ホスト',
                                user='ユーザ名',
                                password='パスワード',
                                db='DB名',
                                charset='utf8',
                                cursorclass=pymysql.cursors.DictCursor)
    # select
    # SQLを実行する
    cursor = conn.cursor()
    sql = "SELECT * FROM test WHERE target_flag = 1"
    cursor.execute(sql)

    # Select結果を取り出す
    rets = cursor.fetchall()
    for r in rets:
        print(r)

    # MySQLから切断する
    conn.close()

実行すると、下記の状態で出力されましたので無事に取れているかと思います。

{u'target_flag': 1, u'id': 1, u'name': u'A\u3055\u3093'}
{u'target_flag': 1, u'id': 2, u'name': u'B\u3055\u3093'}
{u'target_flag': 1, u'id': 3, u'name': u'C\u3055\u3093'}
{u'target_flag': 1, u'id': 5, u'name': u'E\u3055\u3093'}

ちなみに、cursorclass=pymysql.cursors.DictCursorを外すと、結果は下記になります。

{1, 1, u'A\u3055\u3093'}
{1, 2, u'B\u3055\u3093'}
{1, 3, u'C\u3055\u3093'}
{1, 5, u'E\u3055\u3093'}

アクセスの仕方が変わるので、、cursorclass=pymysql.cursors.DictCursorは付けたほうが良いと思います!

今回ハマったこと

上記のソースなんですが、1回目は正常に取れましたが、2度目からコンソールに何も出力されない事象が起きました。
そこで、改めてソースを見直して、これか?と思う箇所を直して見ました。

mysql.py
# -*- coding: utf-8 -*-
# # モジュール読み込み
import pymysql.cursors

def lambda_handler(event, context):
    # MySQLに接続する
    conn = pymysql.connect(host='ホスト',
                                user='ユーザ名',
                                password='パスワード',
                                db='DB名',
                                charset='utf8',
                                cursorclass=pymysql.cursors.DictCursor)
    # select
    # SQLを実行する
    cursor = conn.cursor()
    sql = "SELECT * FROM test WHERE target_flag = 1"
    cursor.execute(sql)

    # Select結果を取り出す
    rets = cursor.fetchall()
    for r in rets:
        print(r)
    # cursorを閉じる
    cursor.close()

    # MySQLから切断する
    conn.close()

そうです。CURSORのクローズをしていませんでした・・・今一ここでいうCURSORがどういったものか理解できてませんが、1回目の実行結果をfeatchallで全部取得→全て読み込み終える→closeしてないのでメモリ上残っている?→2回目以降も同じ箇所の読み取りなので、メモリ情報変わらず?
なんでしょうか・・・?ちょっとこの辺りが気になるので、落ち着いたら調べたり・色々試したりしたいですね。

INSERTやUPDATE、DELETEについて

これはまぁ、単純にSQL文を書いて実行し、最後にcommitするだけでした。

    cursor = conn.cursor()
    sql = "DELETE * FROM test WHERE target_flag = 0"
    cursor.execute(sql)
    conn.commit()
2
4
0

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
2
4