【问题标题】:Get all models from flask-sqlalchemy db从 flask-sqlalchemy db 获取所有模型
【发布时间】:2014-12-18 08:06:45
【问题描述】:

在 SQLAlchemy 中构建数据库后,我想获取所有模型,即代表它们的类

>>> db
<SQLAlchemy engine='postgresql:///example'>
>>> ???
[<db.Model 'User'>, <db.Model 'Comment'>, <db.Model 'Article'>]

这可以实现吗?怎么样?

我可以很好地获得表格,但不是模型。例如:

>>> for t in db.metadata.tables.items():
        print(t)

这给出了表格而不是模型本身

【问题讨论】:

    标签: flask sqlalchemy flask-sqlalchemy


    【解决方案1】:

    有几个相关的问题,但我没有看到任何完全相同的问题。

    使用您的代码获取表名,并使用this question 接受的答案来获取类,我们可以将类与您的数据库中注册的表名进行匹配。

    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])])
    

    models 是在您的数据库中注册的模型列表。

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

    【讨论】:

      【解决方案2】:

      如果您只需要类,有一个更简单的解决方案。我是根据Celeo’s answer提出来的:

      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)]
      

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

      【讨论】:

        【解决方案3】:

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

        models = {
            mapper.class_.__name__: mapper.class_
            for mapper in db.Model.registry.mappers
        }
        

        详情见this issue

        【讨论】:

          【解决方案4】:

          这在我的情况下有效:略短;更具可读性

          models = []
          for name, thing in db_table_creation.__dict__.iteritems():
              if isinstance(thing, sqlalchemy.ext.declarative.DeclarativeMeta) and hasattr(thing, '__tablename__'):
                  models.append(thing)
          

          【讨论】:

          • db_table_creation 是从哪里来的
          【解决方案5】:

          这是我对Celeo’s answer 的变体,带有打字和简洁的中间步骤:

          from ??? import db  # Import from wherever you have this, or use GergelyPolonkai's method to get a db object.
          from typing import List, Dict, Union
          from flask_sqlalchemy import DefaultMeta
          from sqlalchemy.ext.declarative.clsregistry import _ModuleMarker
          
          registered_classes: List[Union[DefaultMeta, _ModuleMarker]] = \
              [x for x in db.Model._decl_class_registry.values()]
          registered_models: List[DefaultMeta] = \
              [x for x in registered_classes if isinstance(x, DefaultMeta)]
          tables: List[DefaultMeta] = \
              [x for x in registered_models if hasattr(x, '__tablename__')]
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2015-05-26
            • 2021-12-31
            • 2020-05-15
            • 1970-01-01
            • 2013-10-12
            • 1970-01-01
            • 2014-09-17
            相关资源
            最近更新 更多