【问题标题】:How does Flask-SQLAlchemy create_all discover the models to create?Flask-SQLAlchemy create_all 如何发现要创建的模型?
【发布时间】:2015-09-13 23:15:37
【问题描述】:

Flask-SQLAlchemy 的db.create_all() 方法创建与我定义的模型相对应的每个表。我从不实例化或注册模型的实例。它们只是继承自db.Model 的类定义。它怎么知道我定义了哪些模型?

【问题讨论】:

    标签: python flask sqlalchemy flask-sqlalchemy


    【解决方案1】:

    您需要在所有模型所在的同一模块中调用create_all()。如果它们在单独的模块中,您需要在调用create_all()之前将它们全部导入。 SQLAlchemy 查看从db.Model 继承了哪些模型,它只会看到已导入的模型。它将为每个模型创建相应的表。还解释了here

    【讨论】:

    • 我找到了globals() 内置方法(docs.python.org/3.4/library/functions.html#globals),它列出了当前模块中的所有符号。遍历结果并过滤继承 db.Model 的类似乎是一个非常简单的解决方案。
    • 其实不需要遍历模块中的所有类。如果所有模型都已导入,则 db.Model.__subclasses__() 将为您提供从 db.Model 继承的所有类
    【解决方案2】:

    Flask-SQLAlchemy 没有什么特别之处,它都是 SQLAlchemy 的标准部分。

    调用db.create_all 最终调用db.Model.metadata.create_all。表格是associated with a MetaData instance as they are defined。确切的机制在 SQLAlchemy 中非常迂回,因为有很多幕后的簿记正在进行,所以我大大简化了解释。

    db.Model 是一个declarative base class,它有一些特殊的元类行为。当它被定义时,它会在内部创建一个MetaData 实例来存储它为模型生成的表。当您对db.Model 进行子类化时,其元类行为会记录db.Model._decl_class_registry 中的类以及db.Model.metadata 中的表。


    只有在导入包含它们的模块时才定义类。如果你有一个模块 my_models 写在某处,但它从未被导入,它的代码永远不会执行,因此模型永远不会注册。

    这可能是关于 SQLAlchemy 如何检测模型的一些混淆的来源。没有为子类“扫描”任何模块,db.Model.__subclasses__ 没有被使用,但是在某处导入模块代码执行所必需的。

    1. 导入并执行包含模型的模块。
    2. 执行模型类定义,子类db.Model
    3. 模型的表注册到db.Model.metadata

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-03-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-01-11
      • 2022-01-14
      • 2015-06-02
      • 1970-01-01
      相关资源
      最近更新 更多