If you need to constantly de-instruct the class, simply remove the cartographer:
sqlalchemy.orm.class_mapper(Worker).dispose()
The SQLAlchemy toolkit lives like property descriptors of a class object. Therefore, if you need separate, de-instrumented versions of objects, you need to create a version of the class that does not have descriptors in the type hierarchy.
A good way would be to have a constant subclass for each class of the model and create markers for the constant classes. Here's a class decorator that subclasses for you and adds it as a class attribute in the original:
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
You would use it in the definition as follows:
@deinstrumentable class Worker(object): def earnings(self): return self.wage*self.hours mapper(Worker, workers)
And when you have a permanent object, you can create its version with de-instrumentation as follows:
worker = session.query(Worker).first() detached_worker = worker.deinstrument()
You can create a deinstrumented version directly as follows:
detached_worker = Worker.Base()
source share