当前位置: 首页 > 面试题库 >

在不参考应用程序的情况下在蓝图模型中使用Flask-SQLAlchemy

温嘉赐
2023-03-14
问题内容

我正在尝试使用蓝图在Flask中创建一个“模块化应用程序”。

但是,在创建模型时,我遇到了必须引用该应用程序才能获取dbFlask-SQLAlchemy提供的-object的问题。我希望能够在多个应用程序中使用一些蓝图(类似于Django应用程序的使用方式),所以这不是一个好的解决方案。*

  • 可以进行切换,让蓝图创建db实例,然后由应用程序将其与其余的蓝图一起导入。但是随后,任何其他希望创建模型的蓝图都需要从该蓝图而不是应用程序中导入。
    因此,我的问题是:

  • 有没有一种方法可以让蓝图定义模型,而又不知道它们以后将使用的应用程序-并且有多个蓝图组合在一起?我的意思是必须从你的蓝图导入应用程序模块/软件包。

  • 我从一开始就错了吗?蓝图是否不是要独立于应用程序并可以重新分发(例如Django应用程序)?
    如果没有,那么你应该使用什么模式来创建类似的东西?烧瓶扩展?你是否应该简单地做到这一点-也许集中所有模型/方案以及Ruby on Rails?
    编辑:我现在一直在考虑这个问题,这可能与SQLAlchemy而不是Flask有关,因为declarative_base()在声明模型时必须具有。而这得从什么地方来的,反正!

也许最好的解决方案是像Ruby on Rails一样,将项目的模式定义在一个位置并进行分散。声明性SQLAlchemy类定义实际上更像是schema.rb,而不是Django的models.py。我想这也将使使用迁移(从Alembic或sqlalchemy-migrate)更容易。

我被要求提供一个示例,所以让我们做一些简单的事情:假设我有一个描述“ flatpages”的蓝图,这是存储在数据库中的简单,“静态”内容。它使用仅包含短名称(用于URL),标题和正文的表。这是simple_pages/__init__.py

from flask import Blueprint, render_template
from .models import Page

flat_pages = Blueprint('flat_pages', __name__, template_folder='templates')

@flat_pages.route('/<page>')
def show(page):
    page_object = Page.query.filter_by(name=page).first()
    return render_template('pages/{}.html'.format(page), page=page_object)

然后,最好让这个蓝图定义自己的模型(位于中simple_page/models.py):

# TODO Somehow get ahold of a `db` instance without referencing the app
# I might get used in!

class Page(db.Model):
    name = db.Column(db.String(255), primary_key=True)
    title = db.Column(db.String(255))
    content = db.Column(db.String(255))

    def __init__(self, name, title, content):
        self.name = name
        self.title = title
        self.content = content

问题答案:

我相信最真实的答案是模块化蓝图不应该直接与数据访问相关,而应该依赖于提供兼容实现的应用程序。

因此,给出你的示例蓝图。

from flask import current_app, Blueprint, render_template

flat_pages = Blueprint('flat_pages', __name__, template_folder='templates')

@flat_pages.record
def record(state):
    db = state.app.config.get("flat_pages.db")

    if db is None:
        raise Exception("This blueprint expects you to provide "
                        "database access through flat_pages.db")

@flat_pages.route('/<page>')
def show(page):
    db = current_app.config["flat_pages.db"]
    page_object = db.find_page_by_name(page)
    return render_template('pages/{}.html'.format(page), page=page_object)

因此,没有什么可以阻止你提供默认实现的。

def setup_default_flat_pages_db(db):
    class Page(db.Model):
        name = db.Column(db.String(255), primary_key=True)
        title = db.Column(db.String(255))
        content = db.Column(db.String(255))

        def __init__(self, name, title, content):
            self.name = name
            self.title = title
            self.content = content

    class FlatPagesDBO(object):
        def find_page_by_name(self, name):
            return Page.query.filter_by(name=name).first()

    return FlatPagesDBO()

并在你的配置中。

app.config["flat_pages.db"] = setup_default_flat_pages_db(db)

通过不依赖于db.Model的直接继承,可以使上述内容更简洁,而仅使用来自sqlalchemy的vanilla declarative_base,但这应该代表了它的要旨。



 类似资料:
  • 问题内容: 我想实现一个可以使用flask-script停止flask应用程序的命令。我已经搜索了一段时间。因为该框架不提供“ app.stop()” API,所以我对如何编写此代码感到好奇。我正在使用Ubuntu 12.10和Python 2.7.3。 问题答案: 如果仅在桌面上运行服务器,则可以公开终结点以终止服务器: 这是另一种包含更多的方法: 让我知道是否有帮助。

  • 问题内容: 通常,要将调试器附加到正在运行的jvm,您需要使用以下参数启动jvm: 现在,如果我要调试不是在调试模式下启动的进程,该怎么办? 当生产系统(即在没有调试args的情况下启动)显示“随机”(我用宽松的术语)错误时,就会出现这种情况。因此,我无法使用适当的参数重新启动jvm,因为没人知道如何再次再现该错误。在这种情况下是否不可能附加到JVM? 只是为了澄清,除非将它们以调试方式启动,否则

  • 问题内容: 我正在尝试使用Node.js将带有AngularJS的Hello World构建推送到Heroku中。但是有多个视图(局部)。 我首先不使用ngRoute部署了Hello World,这意味着:没有局部。很好,很顺利。然后,我尝试推送2个简单的局部。但我认为问题在于托管应用程序,同时要求提供部分内容。我知道这不是正确的方法,我需要您的建议。 这是我的index.html: 部分“ te

  • 问题内容: 我已经使用flask-oauthlib实现了一个oauth2服务器和一个oauth2客户端。 当我尝试在本地测试时,客户端返回InsecureTransportError并告诉我应该使用https。 有没有办法在没有https的情况下在本地测试应用程序? 客户端运行在127.0.0.2:5000,服务器运行在127.0.0.1:5000。 问题答案: 你应注意,Oauth2通过SSL层

  • 任何建议什么将是实施这种行为的最佳方式。 谢谢Bsengar

  • 问题内容: 如何在Java程序中打开和关闭调试?如何在不重新编译Java程序的情况下打开和关闭调试? 问题答案: 无需使用IDE进行调试 1)您可以使用Assertions编写Java程序。您随时可以启用/禁用它们。 2)您可以使用配置了log4j.properties的日志。在Java程序中,您可以随时指定信息和调试日志,只要您想显示调试或信息日志等信息,就可以在log4j.properties