概要
Flask(v1.1.x)のチュートリアルを大体やった後、以下の記事を参考にFlask(v1.1.x)+SQLAlchemyでWebアプリを開発途中、
python
>>> from app import db
>>> db.create_al()
でdbがインストールできず、その次のdb.create_all()もできませんでした。。。(記事自体は非常に丁寧でとても参考になりました。)
調べたけどもFlaskのバージョン1.1.xに対応した記事は特になかったので同じような人がいた場合の参考にまとめます。
参考記事
環境
- OS : MaxOS Catalina version 10.15.1
- Python : 3.7.7
- Flask==1.1.2
- Flask-SQLAlchemy==2.4.1
前提
途中(アプリの作成やデータベースの作成)コードについては参考記事をみてください。
以下は、参考記事をもとに作成したアプリケーションのディレクトリ構成です。
(any directory)/
├── flaskmemoapp/
├ ├── __init__.py
├ ├── model.py
├ └── templates/
├ └── index.html
├── Procfile
├── requirements.txt
├── runtime.txt
├── .git/
├── .gitignore
└── venv/
また、__init__.py
とmodel.py
は以下のようになりました。
init.py
import os
from flask import Flask, render_template, g, request, redirect, url_for
from flask_sqlalchemy import SQLAlchemy
from memo.model import init_db, Entry, db
def create_app():
app = Flask(__name__, instance_relative_config=True)
db_uri = os.environ.get(‘DATABASE_URL’) or “postgresql://localhost/flaskmemo”
app.config[‘SQLALCHEMY_DATABASE_URI’] = db_uri
init_db(app)
@app.route(‘/‘)
def hello_world():
entries = Entry.query.all()
return render_template('index.html', entries=entries)
@app.route('/post', methods=['POST'])
def add_entry():
entry = Entry()
entry.title = request.form[‘title’]
entry.body = request.form['body']
db.session.add(entry)
db.session.commit()
return redirect(url_for('hello_world'))
return app
model.py
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
def init_db(app):
db.init_app(app)
class Entry(db.Model):
__tablename__ = "entries"
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(), nullable=False)
body = db.Column(db.String(), nullable=False)
解決方法
どうやらコマンドpython
で開くREPL環境ではいけないらしく、flask shell
を使わないといけないらしい(詳細についてはあまりわかってません)。
実際にpython
のREPL環境とflask run
で開くREPL環境では以下のような違いがありました。
コマンド python
~ $ python
Python 3.7.7 (default, May 19 2020, 10:55:09)
[GCC 7.5.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from flaskmemoapp.model import db
>>> db
<SQLAlchemy engine=None>
コマンド flask shell
$ export FLASK_APP=flaskmemoapp
$ flask shell
Python 3.7.7 (default, May 19 2020, 10:55:09)
[GCC 7.5.0] on linux
App: flaskmemoapp [production]
Instance: /app/instance
>>> from memo.model import db
>>> db
<SQLAlchemy engine=postgres://hogehoge~>
コードを比較してみると、今回はPostgreSQLを使ったのですがpythonのREPL環境ではSQLAlchemyはpostgreSQLのデータベースのパスが入っていません。
どうやら今回のようなコードの場合はアプリのコンテキストなるものが必要になるらしく、それはflask shell
の場合しかアプリのコンテキストで動作するREPL環境を起動してくれないようです。(表面的なことしかわかってないです。。。)
最終的にはflask shell
で
$ flask shell
>>> from memo.model import db
>>> db.create_all()
とするとデータベースが作成されました。
終わりに
Flaskのv1.1.xはまだ出たて(?)のためかあまりQiita内でも情報が探せず、荒い内容の記事にはなったのですが誰かの役に立てれば幸いです。
間違いや補足などがあればコメントお願いします!!!