Flask app.run 创建实体副本?

Flask app.run creates entity duplicates?

我使用了 Python (3.6.4)、Flask (0.12.2)、flask_admin (1.5.1) 和 flask_sqlalchemy (2.3.2) 的简单堆栈.我选择 SQLite 作为我的数据库。

我的项目结构比较简单:

1) shared_db.py

from flask_sqlalchemy import SQLAlchemy 
db = SQLAlchemy()

2) models.py

from shared_db import db

class City(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String)

def fill_data(app):
    with app.app_context():
        db.create_all()
        db.session.add(City(name="Moscow"))
        db.session.add(City(name="New York"))
        db.session.add(City(name="London"))
        db.session.add(City(name="Paris"))
        db.session.commit()

3) model_views.py

from flask_admin.contrib.sqla import ModelView

from models import City

class CityView(ModelView):
    column_display_pk = True    # to force ids to appear in the Admin panel
    column_hide_backrefs = False
    column_list = ("id", "name")


def create_views(admin, db):
    admin.add_view(CityView(City, db.session))

4) app.py

import os

from flask_admin import Admin
from flask import Flask, jsonify, make_response, request

from shared_db import db
from models import fill_data
from model_views import create_views

app = Flask(__name__)
app.config["SECRET_KEY"] = "123456790"
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:////<path to the project>/myDB'
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False

db.init_app(app)
fill_data(app)

admin = Admin(app, 'My app')
create_views(admin, db)

if __name__ == "__main__":
    port = int(os.environ.get('PORT', 5000))
    app.run(host='0.0.0.0', port=port, debug=True)

最后,我删除了 myDB 文件(如果它存在)并且我 运行 使用 python3 app.py 的应用程序。

令人惊讶的是,最终我得到了 8 个城市而不是 4!我使用 DB Browser 进行了一些调试,发现在最后一行代码 app.run(...) 执行后立即创建了重复的 4 个城市。

如何 运行 Flask 应用程序正确使用预填充的数据库?

如果您需要在每次应用程序启动时为数据库设置种子,您将希望填充数据库的行为是幂等的。换句话说,你需要在创建对象之前检查它是否已经存在(因为在你没有删除数据库的情况下,应用程序完全有可能重新启动)。 This post 可能会帮助您使用 SQLAlchemy 完成此行为。