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 完成此行为。
我使用了 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 完成此行为。