gpt4 book ai didi

python - "De-instrument"来自 sqlalchemy ORM 的实例化对象

转载 作者:太空狗 更新时间:2023-10-30 02:50:31 25 4
gpt4 key购买 nike

是否有一种简单的方法可以“取消检测”来自 sqlalchemy 的 ORM 的实例化类,即将其转换为常规对象?

即,假设我有一个映射到工作表的 Worker 类:

class Worker(object):
def earnings(self):
return self.wage*self.hours

mapper(Worker,workers)

其中 workers 是一个包含大量观察结果的反射表。我想这样做的原因是像 worker.earnings() 这样的方法非常慢,因为所有的 sqlalchemy 开销(我的应用程序不需要)。例如,访问 self.wage 比 self.wage 是普通类的属性慢 10 倍左右。

最佳答案

如果你需要永久地销毁一个类,只需处理映射器:

sqlalchemy.orm.class_mapper(Worker).dispose()

SQLAlchemy 检测作为类对象的属性描述符存在。因此,如果您需要对象的单独的取消检测版本,您将需要创建一个类的版本,该版本的类型层次结构中没有描述符。

一个好的方法是为每个模型类创建一个持久化子类,并为持久化类创建映射器。这是一个类装饰器,它为您创建子类并将其作为类属性添加到原始类中:

def deinstrumentable(cls):
"""Create a deinstrumentable subclass of the class."""
def deinstrument(self):
"""Create a non-instrumented copy of the object."""
obj = cls.__new__(cls)
obj.__dict__.update(self.__dict__)
del obj._sa_instance_state
return obj

persistent = type('Persisted%s' % cls.__name__, (cls,), {
'Base': cls,
'deinstrument': deinstrument
})

return persistent

你可以像这样在定义中使用它:

@deinstrumentable
class Worker(object):
def earnings(self):
return self.wage*self.hours

mapper(Worker, workers)

当你有一个持久化对象时,你可以像这样创建它的 deinstrumented 版本:

worker = session.query(Worker).first()
detached_worker = worker.deinstrument()

你可以像这样直接创建一个deinstrumented版本:

detached_worker = Worker.Base()

关于python - "De-instrument"来自 sqlalchemy ORM 的实例化对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2249694/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com