简体   繁体   English

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

[英]How does Flask-SQLAlchemy create_all discover the models to create?

Flask-SQLAlchemy's db.create_all() method creates each table corresponding to my defined models. Flask-SQLAlchemy的db.create_all()方法创建与我定义的模型相对应的每个表。 I never instantiate or register instances of the models. 我从不实例化或注册模型的实例。 They're just class definitions that inherit from db.Model . 它们只是继承自db.Model类定义。 How does it know which models I have defined? 它如何知道我定义了哪些型号?

Flask-SQLAlchemy does nothing special, it's all a standard part of SQLAlchemy. Flask-SQLAlchemy没有什么特别之处,它只是SQLAlchemy的标准部分。

Calling db.create_all eventually calls db.Model.metadata.create_all . 调用db.create_all最终会调用db.Model.metadata.create_all Tables are associated with a MetaData instance as they are defined . 定义时,MetaData实例相关联 The exact mechanism is very circuitous within SQLAlchemy, as there is a lot of behind the scenes bookkeeping going on, so I've greatly simplified the explanation. 在SQLAlchemy中,确切的机制是非常迂回的,因为有很多幕后的簿记正在进行中,所以我大大简化了解释。

db.Model is a declarative base class , which has some special metaclass behavior. db.Model是一个声明性基类 ,它具有一些特殊的元类行为。 When it is defined, it creates a MetaData instance internally to store the tables it generates for the models. 定义它时,它会在内部创建一个MetaData实例,以存储它为模型生成的表。 When you subclass db.Model , its metaclass behavior records the class in db.Model._decl_class_registry as well as the table in db.Model.metadata . 当你继承db.Model ,元类行为记录在类db.Model._decl_class_registry以及在表db.Model.metadata


Classes are only defined when the modules containing them are imported. 仅在导入包含它们的模块时定义类。 If you have a module my_models written somewhere, but it is never imported, its code never executes so the models are never registered. 如果你有一个模块my_models写在某处,但它永远不会导入,它的代码永远不会执行,所以模型永远不会被注册。

This may be where some confusion about how SQLAlchemy detects the models comes from. 这可能是一些关于SQLAlchemy如何检测模型的混淆。 No modules are "scanned" for subclasses, db.Model.__subclasses__ is not used, but importing the modules somewhere is required for the code to execute. 无模块“扫描”的子类, db.Model.__subclasses__不使用,但在导入的地方需要要执行的代码模块。

  1. Module containing models is imported and executed. 导入并执行包含模型的模块。
  2. Model class definition is executed, subclasses db.Model 执行模型类定义,子类为db.Model
  3. Model's table is registered with db.Model.metadata Model的表在db.Model.metadata注册

You need to call create_all() in the same module as all the models are in. If they are in separate modules, you need to import them all before calling create_all() . 您需要在所有模型所在的模块中调用create_all() 。如果它们位于单独的模块中,则需要在调用create_all()之前将它们全部导入。 SQLAlchemy looks at what models have been subclassed from db.Model , and it will only see models that have been imported. SQLAlchemy查看从db.Model子类化的模型,它只会看到已导入的模型。 It will create the corresponding table for each model. 它将为每个模型创建相应的表。 Also explained here . 这里也解释

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM