SQLAlchemy 中的动态类创建
Posted
技术标签:
【中文标题】SQLAlchemy 中的动态类创建【英文标题】:Dynamic Class Creation in SQLAlchemy 【发布时间】:2011-02-15 15:38:24 【问题描述】:我们需要创建 SQLAlchemy 类来访问多个外部数据源,这些数据源的数量会随着时间的推移而增加。我们为核心 ORM 模型使用声明式基础,我知道我们可以使用 autoload=True 手动指定新的 ORM 类来自动生成映射。
问题是我们需要能够动态生成它们,如下所示:
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
stored=
stored['tablename']='my_internal_table_name'
stored['objectname']='MyObject'
并动态地把它变成这样的东西:
class MyObject(Base):
__tablename__ = 'my_internal_table_name'
__table_args__ = 'autoload':True
我们不希望类的持续时间超过打开连接、执行查询然后关闭连接所需的时间。因此,理想情况下,我们可以将上面“存储”变量中的项目放入数据库中,并根据需要拉取它们。另一个挑战是对象名称(例如“MyObject”)可能用于不同的连接,因此我们无法定义一次并保留它。
任何关于如何实现这一点的建议将不胜感激。
谢谢...
【问题讨论】:
【参考方案1】:您可以使用3-argument call to type
动态创建MyObject
:
type(name, bases, dict)
Return a new type object. This is essentially a dynamic form of the
class statement...
例如:
mydict='__tablename__':stored['tablename'],
'__table_args__':'autoload':True,
MyObj=type(stored['objectname'],(Base,),mydict)
print(MyObj)
# <class '__main__.MyObject'>
print(MyObj.__base__)
# <class '__main__.Base'>
print(MyObj.__tablename__)
# my_internal_table_name
print(MyObj.__table_args__)
# 'autoload': True
【讨论】:
男孩……我觉得自己很笨。这么简单的解决方案。我没有意识到 type 方法如此强大。我稍微修改了解决方案,将对象名称放在全局空间中,以便它可以直接包含在 SQLAlchemy 查询中: globals()[stored['objectname']]=type(stored['objectname'],(Base,), mydict)谢谢...很好的解决方案。 别觉得自己笨!我通过观看其他人在 SO 上使用它来学习这个技巧。现在您也知道诀窍了,可以让您的朋友惊叹不已。 :) @unutbu 你需要额外的分隔逗号以便调用 type 意识到它们只是第一个参数吗? 这个线程有点老了,但是我在任何地方都找不到解决方案,如何在 api 调用期间在其他地方重用 MyObj?因为如果我调用工厂两次,就会抛出一个表名已经存在的错误以上是关于SQLAlchemy 中的动态类创建的主要内容,如果未能解决你的问题,请参考以下文章