使用Application Factory模式将应用程序上下文传递给自定义转换器

使用Application Factory模式将应用程序上下文传递给自定义转换器,第1张

概述我目前正在构建一个使用 Application Factory模式的应用程序.在这个应用程序中,我有一个自定义URL转换器,它接受一个整数并返回一个带有该ID的SQLAlchemy模型实例(如果存在).当我没有使用Application Factory模式时,这很好用,但是使用它时,我在访问使用转换器的任何路由时都会收到此错误: RuntimeError: application not regi 我目前正在构建一个使用 Application Factory模式的应用程序.在这个应用程序中,我有一个自定义URL转换器,它接受一个整数并返回一个带有该ID的sqlAlchemy模型实例(如果存在).当我没有使用Application Factory模式时,这很好用,但是使用它时,我在访问使用转换器的任何路由时都会收到此错误:

RuntimeError: application not registered on db instance and no application bound to current context

我的应用程序结构如下所示:

应用程序/ __ init__.py

from flask import Flaskfrom flask_sqlalchemy import sqlAlchemyfrom config import configdb = sqlAlchemy()def create_app(config_name):    app = Flask(__name__)    app.config.from_object(config[config_name])    db.init_app(app)    from app.converters import CustomConverter    app.url_map.converters["custom"] = CustomConverter    from app.vIEws.main import main    app.register_blueprint(main)    return app

应用程序/ converters.py

from werkzeug.routing import ValIDationError,IntegerConverterfrom app.models import SomeModelclass CustomConverter(IntegerConverter):    """ Converts a valID SomeModel ID into a SomeModel object. """    def to_python(self,value):        some_model = SomeModel.query.get(value)        if some_model is None:            raise ValIDationError()        else:            return some_model

应用/视图/ main.py

from flask import Blueprintmain = Blueprint("main",__name__)# This causes the aforementioned [email protected]("/<custom:some_model>")def get_some_model(some_model):    return some_model.name

有没有办法以某种方式将应用程序上下文传递给CustomConverter?我尝试使用current_app.app_context()包装to_python方法的内容,但所有这一切都将错误减少到RuntimeError:在应用程序上下文之外工作.

这是完整的追溯:

file "c:\python34\lib\site-packages\flask\app.py",line 1836,in __call__return self.wsgi_app(environ,start_response)file "c:\python34\lib\site-packages\flask\app.py",line 1812,in wsgi_appctx = self.request_context(environ)file "c:\python34\lib\site-packages\flask\app.py",line 1773,in request_contextreturn RequestContext(self,environ)file "c:\python34\lib\site-packages\flask\ctx.py",line 247,in __init__self.match_request()file "c:\python34\lib\site-packages\flask\ctx.py",line 286,in match_requestself.url_adapter.match(return_rule=True)file "c:\python34\lib\site-packages\werkzeug\routing.py",line 1440,in matchrv = rule.match(path)file "c:\python34\lib\site-packages\werkzeug\routing.py",line 715,in matchvalue = self._converters[name].to_python(value)file "c:\Users\Encrylize\Desktop\Testing\Flask\app\converters.py",line 8,in to_pythonsome_model = SomeModel.query.get(value)file "c:\python34\lib\site-packages\flask_sqlalchemy\__init__.py",line 428,in __get__return type.query_class(mapper,session=self.sa.session())file "c:\python34\lib\site-packages\sqlalchemy\orm\scoping.py",line 71,in __call__return self.registry()file "c:\python34\lib\site-packages\sqlalchemy\util\_collections.py",line 988,in __call__return self.registry.setdefault(key,self.createfunc())file "c:\python34\lib\site-packages\flask_sqlalchemy\__init__.py",line 136,in __init__self.app = db.get_app()file "c:\python34\lib\site-packages\flask_sqlalchemy\__init__.py",line 809,in get_appraise RuntimeError('application not registered on db 'RuntimeError: application not registered on db instance and no application bound to current context
解决方法 我刚遇到同样的问题.我不确定解决它的’正确’方法是什么,因为这似乎是一个相当明显的事情,应该只是工作,但我解决了它与适用于应用工厂模式的大多数问题的通用解决方法:将app对象保存在闭包中并从外部注入.对于你的例子:

def converters(app):    class CustomConverter(IntegerConverter):        """ Converts a valID SomeModel ID into a SomeModel object. """        def to_python(self,value):            with app.app_context():                some_model = SomeModel.query.get(value)                if some_model is None:                    raise ValIDationError()                else:                    return some_model    return {"custom": CustomConverter}def create_app(config_name):    app = Flask(__name__)    app.config.from_object(config[config_name])    db.init_app(app)    app.url_map.converters.update(converters(app))    from app.vIEws.main import main    app.register_blueprint(main)    return app

显然,这不是优雅或最优的:在URL解析期间创建临时应用程序上下文,然后立即丢弃.

编辑:主要问题:这不适用于非平凡的案件.返回的对象将不会连接到实时会话(临时应用程序上下文关闭时会清理会话).修改和延迟加载将中断.

总结

以上是内存溢出为你收集整理的使用Application Factory模式将应用程序上下文传递给自定义转换器全部内容,希望文章能够帮你解决使用Application Factory模式将应用程序上下文传递给自定义转换器所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1197458.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-03
下一篇 2022-06-03

发表评论

登录后才能评论

评论列表(0条)

保存