Flask app.run创建实体重复?

时间:2018-04-10 22:08:39

标签: python sqlite flask flask-sqlalchemy flask-admin

我使用简单的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 !我使用数据库浏览器执行一些调试,发现重复的4个城市在最后一行代码 - app.run(...) - 执行后立即创建。

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

1 个答案:

答案 0 :(得分:2)

如果您需要在每次应用程序开始时为数据库设定种子,您将需要使填充数据库的行为具有幂等性。换句话说,您需要在创建对象之前检查对象是否已存在(因为完全可能是在您未删除数据库时应用程序重新启动)。 This post可以帮助您使用SQLAlchemy完成此行为。