はじめに
Postgresを使ったFlaskのアプリケーションをHerokuデプロイにはまっていたのでメモ。
Flask-SQLAlchemyというFlask拡張ORMを使います。
Flask-SQLAlchemy公式よりこのサイトの方がわかりやすかった。
FlaskのインストールやDBを使わないHerokuデプロイは既にできている状態から始めます。
簡単な用語の説明
-
SQLAlchemy
- PythonのためのDBツールキットでありORM
-
flask-sqlalchem
- SQLAlchemyをFlaskで動かすための拡張
-
psycopg
- Python用のPostgreSQLアダプタ
ライブラリのインストール
$ pip install flask-sqlalchemy psycopg2
requirements.txtを書き込みするFlaskでのおきまりの作業
$ pip freeze > requirements.txt
データベース接続・モデル作成・データ挿入
Userモデルとユーザーidに紐づくTaskモデルという2つのモデルを扱う例です。
Herokuでうまくいくには以下のようにDATABASE_URLを明示してDB接続をする必要があります。
app.config['SQLALCHEMY_DATABASE_URI'] = os.environ['DATABASE_URL']
app.py
from flask.ext.sqlalchemy import SQLAlchemy
from flask import Flask, render_template, request
# DB接続に関する部分
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = os.environ['DATABASE_URL']
db = SQLAlchemy(app)
# モデル作成
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(80), unique=True)
email = db.Column(db.String(80), unique=True)
def __init__(self, username, email):
self.username = username
self.email = email
def __repr__(self):
return '<User %r>' % self.username
class Task(db.Model):
id = db.Column(db.Integer, primary_key=True)
tasks = db.Column(db.String(80))
user_id = db.Column(db.Integer,db.ForeignKey('user.id'))
def __init__(self, tasks, user_id):
self.tasks = tasks
self.user_id = user_id
def __repr__(self):
return '<Task %r>' % self.tasks
# データベースに追加するコード例
@app.route("/", methods=['POST'])
def register():
if request.method == 'POST':
name= request.form['name']
email = request.form['email']
task = request.form['task']
# emailが未登録ならユーザー追加
if not db.session.query(User).filter(User.email == email).count():
reg = User(name, email)
db.session.add(reg)
db.session.commit()
# タスク追加
user_id= User.query.filter_by(User.email == email).first().id
task = Task(text, user_id)
db.session.add(task)
db.session.commit()
return render_template('success.html') return render_template('index.html')
if __name__ == '__main__':
app.debug = True
app.run()
モデルの作成やデータの挿入は以下のflask-sqlalchemyのドキュメントを参考にしました
Herokuに反映
$ git commit -a -m "added DB boilerplate"
$ git push heroku master
Heroku側にPostgresのアドオンを追加
$ heroku addons:add heroku-postgresql
Heroku先でDBの作成を行う
$heroku run python
>>> from app-name import db
>>> db.create_all()
これでHerokuでもうまく動いているはずです。
以下のようにしてもDB操作が可能です
$heroku run python
>>> from app-name import db,User,Task
>>> User.query.all()
[<User 'userxx'>]
>>> Task.query.all()
...
よく使ったHerokuコマンド(蛇足)
-
heroku run bash
- heroku先にsshみたいな
-
heroku logs -t
- Herokuのログの確認
-
heroku pg:reset DATABASE --confirm app-name
- databaseのリセット