从flask-sqlalchemy db获取所有模型

cor*_*vid 9 sqlalchemy flask flask-sqlalchemy

在SQLAlchemy中构建数据库之后,我想得到所有模型,也就是代表它们的类

>>> db
<SQLAlchemy engine='postgresql:///example'>
>>> ???
[<db.Model 'User'>, <db.Model 'Comment'>, <db.Model 'Article'>]
Run Code Online (Sandbox Code Playgroud)

这可以实现吗?怎么样?

我可以很好地得到表格,而不是模型.例如:

>>> for t in db.metadata.tables.items():
        print(t)
Run Code Online (Sandbox Code Playgroud)

这使得表格不是模型本身

Cel*_*leo 11

有几个相关的问题,但我没有看到任何确切的重复.

使用您的代码获取表名,以及这个问题是获得类的接受答案,我们可以将类与数据库中注册的表名匹配.

classes, models, table_names = [], [], []
for clazz in db.Model._decl_class_registry.values():
    try:
        table_names.append(clazz.__tablename__)
        classes.append(clazz)
    except:
        pass
for table in db.metadata.tables.items():
    if table[0] in table_names:
        models.append(classes[table_names.index(table[0])])
Run Code Online (Sandbox Code Playgroud)

models您的数据库中注册的模型列表在哪里?

try catch是必需的,因为<sqlalchemy.ext.declarative.clsregistry._ModuleMarker object>它将包含在for clazz in ...循环中,并且它没有__tablename__属性.


Ger*_*kai 7

如果您只需要这些类,则有一个更简单的解决方案.我基于Celeo的回答想出了它:

from flask import current_app

# This is to be generic (ie. no need to pass your actual SQLAlchemy instance)
# This way you can include it even in your own extension.
db = current_app.extensions['sqlalchemy'].db

[cls for cls in db.Model._decl_class_registry.values()
 if isinstance(cls, type) and issubclass(cls, db.Model)]
Run Code Online (Sandbox Code Playgroud)

这不需要所有那些额外的辅助变量,只需查询类注册表,并过滤掉不是模型的所有内容.


Gre*_* Li 5

在 SQLAlchemy 1.4 中,该_decl_class_registry.values()方法已删除,您可以db.Model.registry.mappers改用:

models = {
    mapper.class_.__name__: mapper.class_
    for mapper in db.Model.registry.mappers
}
Run Code Online (Sandbox Code Playgroud)

请参阅本期中的详细信息。