at backyard

Color my life with the chaos of trouble.

PythonのFlaskサンプルアプリをpipenv使いつつ、Docker上のMySQLと共に立ち上げる。

ふいにPythonに触りたくなったので、かなり前に書いたこちらの記事を自己参照しながら、久しぶりにFlaskで基本的なWebアプリのサンプル(CRUD)を動かしてみることにした。

shinshin86.hateblo.jp

なお、上の記事にも書いているが、アプリ自体は自身で書いているわけではなく、こちらの方のリポジトリを試させてもらっている。
試しやすくて良いサンプル。感謝。

github.com

当時はpip installしたり、sqlite でやっていたが、pipenv 使ったりDBは docker上のMySQL に変えて再度試してみようと思う。
というわけで、これは個人的な備忘録。

と思ったけど、まずはSQLiteからやっていく

Flask(pipenv使用)。DBはSQLite

# cloneする
git clone https://github.com/tanrax/flask-contacts.git

# pipenvで構築する
pipenv --python 3.7.2

すると、Pipfile が作られるが、このタイミングで requirement.txt に記述のあるライブラリが自動的に反映される

[[source]]
name = "pypi"
url = "https://pypi.org/simple"
verify_ssl = true

[dev-packages]

[packages]
gunicorn = "*"
Faker = "==0.7.11"
Flask = "==1.0"
Flask-SQLAlchemy = "==2.2"
Flask-WTF = "==0.14.2"

[requires]
python_version = "3.7"

これは便利。

# 依存関係のインストール
pipenv install

Pipfileに2つのコマンドを用意する

[scripts]
migrate = "python3 migrations.py"
start = "python3 app.py"

ひとまずはsqlite上でアプリを立ち上げてみる。

# SQLite環境にデータ投入
pipenv run migrate

# startした際に最初アクセスの許可を求められるかもしれないので、許可するを選択
pipenv run start

sqliteのデータについてはmigrate実行時にカレントに book.sqliteというのができているはず。

これでlocalhost:5000にアクセスすればOK

Flask(pipenv使用)。DBはDocker上のMySQLを使用

SQLiteからMySQLに変える。

まずは app.pymodels.py を下記のように修正する
ちなみにDBへの接続の際はパスワードは使用しないようになっているので、このあとのDocker立ち上げ時に MYSQL_ALLOW_EMPTY_PASSWORD=yes環境変数として設定する必要がある。これはこのあと書く。

diff --git a/app.py b/app.py
index 86b483a..ae9e1fd 100644
--- a/app.py
+++ b/app.py
@@ -8,8 +8,8 @@ app.config['SECRET_KEY'] = 'my secret'
 app.config['DEBUG'] = False

 # Database
-app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///book.sqlite'
-# app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://root@localhost/book'
+# app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///book.sqlite'
+app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://root@localhost/book'
 app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
 db.init_app(app)

diff --git a/models.py b/models.py
index 51d3b0a..ce3e342 100644
--- a/models.py
+++ b/models.py
@@ -2,8 +2,8 @@ from flask import Flask
 from flask_sqlalchemy import SQLAlchemy

 app = Flask(__name__)
-app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///book.sqlite'
-#app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://root@localhost/book'
+# app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///book.sqlite'
+app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://root@localhost/book'
 app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
 db = SQLAlchemy(app)

パスワード設定無し(NO password)のMySQLをDockerで立ち上げる

db名はbook、接続ユーザ名はrootが指定されているため、そのとおりに各環境変数を指定する。
上にも書いたが、MYSQL_ALLOW_EMPTY_PASSWORD=yesを指定してパスワードは設定しないようにする。
(当然だが、あくまでテスト用である)

# DB名はbookにする
export DB_NAME=book

docker run -p 3306:3306 --name sample-db  -e MYSQL_USER=$DB_USER -e MYSQL_ALLOW_EMPTY_PASSWORD=yes -e MYSQL_DATABASE=$DB_NAME -d mysql:latest

これで準備OK、のはずだったが、

pipenv run migrate

を打つと、ModuleNotFoundError: No module named 'pymysql' というエラーが出た。

追加でインストールする

pipenv install pymysql

これで再度実行。

pipenv run migrate

mysql上のbookテーブルにデータが入ったのを確認。
あとはstartで立ち上げるのみ。

pipenv run start

以上。