Flask-SQLAlchemy create_all如何发现要创建的模型?

时间:2015-06-26 21:50:19

标签: python flask sqlalchemy flask-sqlalchemy

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

2 个答案:

答案 0 :(得分:13)

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
  4. 注册

答案 1 :(得分:4)

您需要在所有模型所在的模块中调用<!-- I want ? to be a fixed enum value --> <TextBlock Text="{Binding ?, Converter={StaticResource=UserStatusToString}}" Foreground={Binding ?, Converter={StaticResource=UserStatusToBrush}} /> 。如果它们位于不同的模块中,则需要在调用create_all()之前将它们全部导入。 SQLAlchemy查看从create_all()子类化的模型,它只会看到已导入的模型。它将为每个模型创建相应的表。还解释了here