【Python】Flask + MySQL + SQLAlchemyでAPIを開発してみよう Part2

2019.09.09

Pythonはじめました

 

 

こんにちは、せんだです。

 

ようやく夏の厳しい暑さが落ちついてきたかな?と思う今日この頃。

と見せかけてまだまだ涼しいとは程遠い(主観です)ので、皆さま体調管理にはお気をつけ下さいませ。

 

さて、前回に引き続きPythonの軽量フレームワーク「Flask」を使ったAPIの作り方について書きます。

 

前回の記事はこちら

【Python】Flask + MySQL + SQLAlchemyでAPIを開発してみよう Part1

 

前回はFlaskのインストール、ルーティング、レスポンスの雛形をとりあえず作りました。

今回やることはこちら。

 

今回やること

  • モジュールのインストール
  • DB連携の設定
  • モデルの作成
  • 取得したデータをJSON形式で返す

 

環境

端末:Mac Book Pro

Pythonバージョン: 3.6.8

Flaskバージョン: 1.0.3

MySQLバージョン: 5.7

SQLAlchemy バージョン:1.3.4

 

ディレクトリ構成

 

ディレクトリ構成はこんな感じです。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
app.py ... 起動ファイル
|
config.py ... 設定ファイル
|
api
├── __init__.py ... FlaskApp本体

├── database.py ... DB情報

├── models ... Model群
│   └── users.py
│   └── __init__.py

└── views  ... Controller群
    └── user.py

 

モジュールのインストール

 

今回使うモジュールをインストールします。

1
$ pip install SQLAlchemy, Flask-SQLAlchemy, Flask-Cors, marshmallow, marshmallow-sqlalchemy, flask-marshmallow

 

DB連携の設定

 

DB接続に必要なコードを書いていきます。

 

conifg.py

1
2
3
4
5
6
7
8
9
10
11
12
class SystemConfig:

  DEBUG = True

  SQLALCHEMY_DATABASE_URI = 'mysql+pymysql://{user}:{password}@{host}/{db_name}?charset=utf8'.format(**{
      'user': '<接続ユーザー>',
      'password': '<接続パスワード>',
      'host': '<接続先ホスト>',
      'db_name': '<接続先データベース名>'
  })

Config = SystemConfig

あくまで必要最低限ですが、DBの接続情報を記述しています。

 

最後の

1
Config = SystemConfig

という記述でConfigという名前で外部ファイルから読み込める様にしています。

 

api/database.py

1
2
3
4
5
6
7
8
9
from flask_sqlalchemy import SQLAlchemy
from flask_marshmallow import Marshmallow

db = SQLAlchemy()
ma = Marshmallow()

# アプリでDB操作を行えるように初期設定する
def init_db(app):
  db.init_app(app)

FlaskアプリからSQLAlchemyとMarshmallowを使う為の定義をしています。

MarshmallowというのはPythonのデータ型をJSONに変換したり、またはその逆を行う為のライブラリです。
SQLAlchemyを使って取得したデータは、そのままだとJSONで返せないのでMarshmallowを使ってJSONに
変換します。

 

api/__init__.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
from flask import Flask, make_response, jsonify
from .views.user import user_router
from flask_cors import CORS
from api.database import db
import config

def create_app():

  app = Flask(__name__)

  # CORS対応
  CORS(app)

  # DB設定を読み込む
  app.config.from_object('config.Config')
  db.init_app(app)

  app.register_blueprint(user_router, url_prefix='/api')

  return app

app = create_app()

先ほど設定したconfig.py、database.pyを読み込み、Flaskアプリを起動します。

とりあえず、これでSQLAlchemyを使ったDB連携の下準備が整いました。

 

モデルの作成

 

次はモデルを書いて、SQLAlChemyを使って、データの操作を行います。

 

api/models/user.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
from api.database import db, ma

class User(db.Model):
  __tablename__ = 'users'

  id = db.Column(db.Integer, primary_key=True, autoincrement=True)
  name = db.Column(db.String(50), nullable=False)
  address= db.Column(db.String(100), nullable=True)
  tel = db.Column(db.String(20), nullable=True)
  mail = db.Column(db.String(100), nullable=True)

  def __repr__(self):
    return '<User %r>' % self.name

  def getUserList():

    # select * from users
    user_list = db.session.query(User).all()

    if user_list == None:
      return []
    else:
      return user_list

  def registUser(user):
    record = User(
      name = user['name'],
      address = user['address'],
      tel = user['tel'],
      mail = user['mail']
    )
   
    # insert into users(name, address, tel, mail) values(...)
    db.session.add(record)
    db.session.commit()

    return user

class UserSchema(ma.ModelSchema):
    class Meta:
      model = User
      fields = ('id', 'name', 'address', 'tel', 'mail')

こんな感じにDBの構造を定義します。

下の方に書いたのは、ユーザー一覧取得用のメソッドと登録用のメソッドです。

 

1
2
3
4
class UserSchema(ma.ModelSchema):
    class Meta:
      model = User
      fields = ('id', 'name', 'address', 'tel', 'mail')
この部分はMarshmallowで使用するスキーマを定義しています。

 

取得したデータをJSON形式で返す

 

最後にモデルを使って、DB操作を行いJSON形式でレスポンスします。

 

api/views/user.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
from flask import Blueprint, request, make_response, jsonify
from api.models import User, UserSchema
import json

# ルーティング設定
user_router = Blueprint('user_router', __name__)

@user_router.route('/users', methods=['GET'])
def getUserList():

  users = User.getUserList()
  user_schema = UserSchema(many=True)

  return make_response(jsonify({
    'code': 200,
    'users': user_schema.dump(users).data
  }))

@user_router.route('/users', methods=['POST'])
def registUser():

  # jsonデータを取得する
  jsonData = json.dumps(request.json)
  userData = json.loads(jsonData)

  user = User.registUser(userData)
  user_schema = UserSchema(many=True)

  return make_response(jsonify({
    'code': 200,
    'user': user
  }))

先ほど、準備したモデルを使ってコントローラーを記述します。

上記のようにModelを読み込む際は api/models/__init__.pyに下記を追記します。

 

api/models/__init__.py

1
from .user import User, UserSchema

 

確認

 

api/usersにPOST、GETでアクセスするとそれぞれステータス200が返ってくるかと思います。

[GET] api/users

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# レスポンス

{
  "code": 200,
  "users": [
    {
      "address": "茨城県つくば市千現",
      "id": 1,
      "mail": "ichirou@swallow-incubate.com",
      "name": "鈴木一郎",
      "tel": "0281234567"
    },
    {
      "address": "茨城県つくば市千現",
      "id": 2,
      "mail": "jirou@swallow-incubate.com",
      "name": "佐藤二郎",
      "tel": "0281234567"
    }
  ]
}

 

[POST] api/users

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# リクエストbody

{
  "name": "山田太郎",
  "address":"茨城県つくば市千現",
  "tel":"02812345678",
  "mail":"blogtest@swallow-incubate.com"
}
 

# レスポンス

{
  "code": 200,
  "user": {
    "address": "茨城県つくば市千現",
    "mail": "blogtest@swallow-incubate.com",
    "name": "山田太郎",
    "tel": "0281234567"
  }
}

 

まとめ

今回はFlaskとSQLAlchemyを使って実際にMySQLとの連携部分を実装しました。

ここまでで、とりあえずFlask + MySQL + SQLAlchemyでWeb APIを作る事ができたと思います。

それでは、また次回!


Top