使用 Flask-SQLAlchemy 和蓝图循环导入数据库引用 [英] Circular import of db reference using Flask-SQLAlchemy and Blueprints
问题描述
我正在使用 Flask-SQLAlchemy 和 Blueprints,我无法使用循环导入.我知道我可以在函数内部编写导入并使其工作,但这听起来很糟糕,我想与社区确认是否有更好的方法来做到这一点.
I am using Flask-SQLAlchemy and Blueprints and I cannot help myself from using circular imports. I know I can write imports inside functions and make it work but it sounds nasty, I'd like to confirm with the community if there is a better way to do this.
问题是我有一个模块 (blueprints.py),我在其中声明数据库并导入蓝图,但这些蓝图需要同时导入数据库声明.
The problem is I have a module (blueprints.py) where I declare the database and import the blueprints but those blueprints need to import the database declaration at the same time.
这是代码(重要部分的摘录):
This is the code (excerpt of the important parts):
from application.blueprints import db
people = Blueprint('people', __name__,
template_folder='templates',
static_folder='static')
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(80), unique=True)
@people.route('/all')
def all():
users = User.query.all()
application.blueprints.py
from application.apps.people.views import people
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:////tmp/test.db'
db = SQLAlchemy(app)
app.register_blueprint(people, url_prefix='/people')
我已阅读有关此主题的文档和问题,但仍然找不到我要寻找的答案.我找到了这一章(https://pythonhosted.org/Flask-SQLAlchemy/contexts.html) 建议将初始化代码放在方法中,但循环导入仍然存在.
I have read the documentation and the questions I found on this topic, but I still cannot find the answer I am looking for. I have found this chapter (https://pythonhosted.org/Flask-SQLAlchemy/contexts.html) where it suggest to put the initialization code inside a method but the circular import still persist.
编辑我使用模式 Application Factory
推荐答案
我在 应用工厂 模式.我在第三个模块中声明数据库,稍后在启动应用程序的同一模块中配置它.
I fixed the problem with the help of the Application Factory pattern. I declare the database in a third module and configure it later in the same module in which I start the application.
这会导致以下导入:
- database.py → app.py
- views.py → app.py
- database.py → views.py
没有循环导入.在调用数据库操作之前确保应用程序已启动和配置非常重要.
There is no circular import. It is important to make sure that the application was started and configured before calling database operations.
这是一个示例应用程序:
Here is an example application:
app.py
from database import db
from flask import Flask
import os.path
from views import User
from views import people
def create_app():
app = Flask(__name__)
app.config['DEBUG'] = True
app.config['SQLALCHEMY_DATABASE_URI'] = "sqlite:////tmp/test.db"
db.init_app(app)
app.register_blueprint(people, url_prefix='')
return app
def setup_database(app):
with app.app_context():
db.create_all()
user = User()
user.username = "Tom"
db.session.add(user)
db.session.commit()
if __name__ == '__main__':
app = create_app()
# Because this is just a demonstration we set up the database like this.
if not os.path.isfile('/tmp/test.db'):
setup_database(app)
app.run()
database.py
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
views.py
from database import db
from flask.blueprints import Blueprint
people = Blueprint('people', __name__,
template_folder='templates',
static_folder='static')
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(80), unique=True)
@people.route('/')
def test():
user = User.query.filter_by(username="Tom").first()
return "Test: Username %s " % user.username
这篇关于使用 Flask-SQLAlchemy 和蓝图循环导入数据库引用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!