LoginSignup
5
3

More than 3 years have passed since last update.

mysqlから持って来たデータをjsonで返すapiをflaskで作る

Last updated at Posted at 2018-12-12

動機

pythonのflaskを使って、MySQLから持って来たデータをjson形式で返すAPIを作りたい

はまったところ

1.MySQLから持って来たデータをどうやってjson形式(≒辞書型)にするか
2.辞書型で取り出した後に遭遇した TypeError: Object of type 'datetime' is not JSON serializable というエラー

解決策

1.普通にデータを取得するとタプルで返ってくるが、下記のようにdictionary=Trueを渡すと辞書型で返ってくる。


query = 'SELECT * FROM tablename WHERE dataid = ' + str(dataid)
cursor = conn.cursor(dictionary=True)
cursor.execute(query)

2.TypeError: Object of type 'datetime' is not JSON serializableの対策

[Python] dateやdatetimeをjson.dumpでエラーなく出力する

ここを参考に、下記のような処理を挟んだ。


def json_serial(obj):
    if isinstance(obj, (datetime, date)):
        return obj.isoformat()
    elif isinstance(obj, timedelta):
        return str(obj)
    raise TypeError("Type %s not serializable" % type(obj))

mysqlの結果がdatetimeだったりすると見出しにあるエラーが出るので、個別に処理している。
また、timedeltaについてはdatetimeと同様の処理だと下記のエラーが出るので上のソースでは別処理として追記している。
'datetime.timedelta' object has no attribute 'isoformat'

全体のソース

下記は例です

from flask import Flask, send_file, make_response, jsonify
import requests
from datetime import datetime, date, timedelta
import json
import mysql.connector

app = Flask(__name__, static_folder=None)

def json_serial(obj):
    if isinstance(obj, (datetime, date)):
        return obj.isoformat()
    elif isinstance(obj, timedelta):
        return str(obj)
    raise TypeError("Type %s not serializable" % type(obj))

@app.route('/data/<string:dataid>', methods=['GET'])
def getData(param, dataid):
    response_data = {}

    conn = mysql.connector.connect(
        host='hostname',
        port=3306,
        user='dbuser',
        password='dbpass',
        database='dbname',
    )

    query = 'SELECT * FROM tablename WHERE dataid = ' + str(dataid)
    cursor = conn.cursor(dictionary=True)
    cursor.execute(query)
    data = cursor.fetchall()
    conn.close()

    response_data["body"] = data
    response_data["status"] = "200"

    return make_response(json.dumps(response_data, default=json_serial))

# main
if __name__ == "__main__":
    print(app.url_map)
    app.run(host='localhost', port=5000)

参考にしたページ

[Python] dateやdatetimeをjson.dumpでエラーなく出力する

追記:MySQLdbを使う場合

事前に pip install mysqlclient でインストールをしておいて、下記で行けるようです。

connection = MySQLdb.connect(
        host='localhost', user='root', passwd='testpass', db='sample_db', charset='utf8')
    cursor = connection.cursor(MySQLdb.cursors.DictCursor)
5
3
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
5
3