Elastic Beanstalk+RDSでMySQLを利用する

前回、Elastic BeanstalkでFlaskのアプリをデプロイしてみた。

Elastic BeanstalkにFlaskのアプリをデプロイしてみた

ビーンスタークはWebアプリを置いてくれたが、DBが無いとデータが保存できないので別でDBが必要になる。

AWSにはいろんなDBサービスがあるが、今回はRDSを使う。

RDSの作成

ビーンスタークの環境の設定画面にいくと、下の方にデータベースがある。

写真ではすでに追加済みだが、初期は何も書かれていない。

ここの編集からデータベースを追加する。

6種類くらいの中から「mysql」を選択して、接続するためのユーザ名とパスワード(8文字以上)を入力。

数分経つとDBが出来上がり、RDSの画面からDBが作成できているのが確認できる。

このままだとローカルPCからは接続できないので、ローカルPCのIPアドレスを追加する。

DB識別子をクリック。

セキュリティグループをクリック。

インバウンドルールの中に、「インバウンドルールを編集」の項目がある。

「自宅のグローバルIP/32」を指定して追加する。

セキュリティを考慮しなければ、0.0.0.0/0にして、どのIPからもアクセス可能にすることもできる。

ちなみに、1つ目のルールは初めから存在し、ビーンスタークの環境(EC2)からアクセスできるようにするものだと思われる。

ローカルから接続してテーブルを作成する

Flask-SQLAlchemyを使って、テーブルを作成してみる。

__init__.py

from flask_sqlalchemy import SQLAlchemy
from short_service import application

db = SQLAlchemy(application)

base.py

import datetime

from short_service.models import db


class ShortURL(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    originalUrl = db.Column(db.String(200), unique=False, nullable=False)
    shortUrlKey = db.Column(db.String(20), unique=True, nullable=False)
    count = db.Column(db.Integer, default=0)
    created_at = db.Column(db.DateTime, default=datetime.datetime.now)
    updated_at = db.Column(db.DateTime, default=datetime.datetime.now, onupdate=datetime.datetime.now)

    def __repr__(self):
        return 'ShortURL(id={0}, origin={1}, key={2}, count={3}, cr_at={4}, up_at{5})'.format(
            self.id, self.originalUrl, self.shortUrlKey, self.count, self.created_at, self.updated_at
        )

作成したDBの認証情報(ユーザー名、PW、ホスト名)をコードに記載する。

config.py

import os

isDev = False
SQLALCHEMY_TRACK_MODIFICATIONS = False

if isDev:
    DEBUG = True
    current_dir = os.getcwd()
    SQLALCHEMY_DATABASE_URI = 'sqlite:////' + current_dir + '/test.db'
else:
    SQLALCHEMY_DATABASE_URI = 'mysql+pymysql://ユーザー名:パスワード@ホスト名:3306/データベース名?charset=utf8'

ちなみに仮想環境に「pymysql」が入っていないとエラーが出る。

私はAnacondaを使っているので、Anacondaナビゲータでインストールした。

Python Consoleで以下のコマンドを打つ。

>>> from short_service.models import base, db
>>> db.create_all()
>>> base.ShortURL.query.all()
[]

テーブルが作成され、空のデータが表示された。

アプリのデプロイ

いつも通りEBにアプリをデプロイして動作確認をする。

eb deploy --staged flask-env
eb open flask-env

Gitを使っていてコミットが面倒な場合には、–stagedオプションをつけておけばコミットしていない変更された(ステージングにある)コードをアップロードできる。

おまけ:502 bad gateway

デプロイした時にBad Gatewayが発生したことがあった。

requirements.txtのファイル名が間違っていたのが原因。