SQLAlchemy:从表名中获取模型。据我所知,这可能意味着将一些函数附加到元类构造函数

新手上路,请多包涵

我想创建一个函数,给定一个表的名称,返回具有该 名的模型。例如:

 class Model(Base):
    __tablename__ = 'table'
    ...a bunch of Columns

def getModelFromTableName(tablename):
   ...something magical

所以 getModelFromTableName(‘table’) 应该返回模型类。

我的目标是在我制作的简单表单生成器中使用该函数,因为 FormAlchemy 不适用于 python3.2,我希望它能够很好地处理外键。

谁能给我任何关于如何让 getModelFromTableName 工作的指示?

这是我的一个想法(这可能是完全错误的,我以前没有使用过元类……)

如果我要让我的模型类继承自 Base 以及其他一些类 (TableReg) 并让 TableReg 存储模型的类元,该怎么办。 某些 全局字典或单例中的表名。

我意识到这可能完全不对,因为 Base 的元类做了一些我不想破坏的非常重要和非常漂亮的东西,但我认为必须有一种方法可以将一些构造函数代码附加到元类我的模型。或者我不明白。

原文由 Sheena 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 772
2 个回答

Eevee 评论的启发:

 def get_class_by_tablename(tablename):
  """Return class reference mapped to table.

  :param tablename: String with name of table.
  :return: Class reference or None.
  """
  for c in Base._decl_class_registry.values():
    if hasattr(c, '__tablename__') and c.__tablename__ == tablename:
      return c

原文由 OrangeTux 发布,翻译遵循 CC BY-SA 3.0 许可协议

因此,在 SQLAlchemy 版本 1.4.x(我更新到 2020 年 3 月 16 日左右)中,似乎 _decl_class_registry 不再存在。

我能够使用新的 registry 类属性(不受保护,所以希望它不会突然被删除!)。

 Base.TBLNAME_TO_CLASS = {}

for mapper in Base.registry.mappers:
    cls = mapper.class_
    classname = cls.__name__
    if not classname.startswith('_'):
        tblname = cls.__tablename__
        Base.TBLNAME_TO_CLASS[tblname] = cls

不确定这是否是最好的方法,但我就是这样做的。

原文由 Erotemic 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题