是否有一种简单的方法可以“取消检测”来自 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/