使用Flask-SQLAlchemy和Blueprints循环导入数据库引用 [英] Circular import of db reference using Flask-SQLAlchemy and Blueprints

查看:559
本文介绍了使用Flask-SQLAlchemy和Blueprints循环导入数据库引用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Flask-SQLAlchemy和Blueprints,我不能自己使用循环导入。
我知道我可以在函数中编写导入,并使其工作,但它听起来很讨厌,我想与社区确认是否有更好的方法来做到这一点。



问题是我有一个模块(blueprints.py),我声明数据库并导入蓝图,但这些蓝图需要同时导入数据库声明。



这是代码(摘录的重要部分):

application.apps.people.views.py



pre $ from application.blueprints import db
$ b $ 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 ),它建议将初始化代码放入方法中,但循环导入仍然存在。
$ b 编辑
我使用应用程序工厂模式解决了问题。

解决方案

我通过应用程序工厂模式。我将数据库声明在第三个模块中,稍后将其配置到启动应用程序的同一个模块中。



结果如下:




  • database.py→app.py

  • views.py→app.py

  • database.py→views.py



没有循环导入。

这是一个示例应用程序:



从数据库导入数据库
从数据库导入数据库导入数据库
从视图导入os.path
导入用户
从视图导入人员

$ b 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

$ b def setup_database(app):
with app.app_context() :
db.create_all()
user = User()
user.username =Tom
db.session.add(user)
db.session。提交()


if __name__ =='__main__':
app = create_app()
#因为这只是一个示范我们这样建立数据库。
如果不是os.path.isfile('/ tmp / test.db'):
setup_database(app)
app.run()

$ b

database.py c> from flask_sqlalchemy import SQLAlchemy

db = SQLAlchemy()

views.py

 从数据库导入db 
从flask.blueprints导入蓝图

$ b $ 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)。 b $ b returnTest:Username%s%user.username


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.

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):

application.apps.people.views.py

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')

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.

Edit I fixed the problem using the pattern 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.

This results in the following imports:

  • 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和Blueprints循环导入数据库引用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆