Flask(v1.1.x)+SQLAlchemyでのdb.create_all()ができない


## 概要
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に対応した記事は特になかったので同じような人がいた場合の参考にまとめます。

参考記事
> [FlaskとPostgreSQLでウェブアプリを作ってHerokuで無料で運用する - Qiita](https://qiita.com/croquette0212/items/9b4dc5377e7d6f292671)


## 環境
* 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

``` __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

```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

```bash
~ $ 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

```bash
$ 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`で

```bash
$ flask shell
>>> from memo.model import db
>>> db.create_all()
```

とするとデータベースが作成されました。

## 終わりに
Flaskのv1.1.xはまだ出たて(？)のためかあまりQiita内でも情報が探せず、荒い内容の記事にはなったのですが誰かの役に立てれば幸いです。
間違いや補足などがあればコメントお願いします！！！