2010-09-29 15 views
6

Quiero pasar una instancia de una clase asignada a un método no compatible con SQLAlchemy (en otro proceso) y solo necesito los valores de mis atributos. El problema es que ocurre un UnboundExecutionError, cada vez que el método quiere leer un valor de atributo. Entiendo, por qué sucede esto, pero me gustaría tener una solución para este problema.Eliminar objeto de la sesión SQLAlchemy

Sólo necesito los valores de mis atributos definidos (id , nombre y sucia en el ejemplo) y no necesitan la sobrecarga SQLAlchemy en el método de destino.

clase Ejemplo:

Ejemplo de llamada:

... 
def do_it(self): 
    records = self.query.filter(Record.dirty == True) 
    for record in records: 
     pass_to_other_process(record) 

He intentado usar session.expunge() y copy.copy(), pero sin éxito.

Respuesta

5

Supongo que estás en conflicto con la carga lenta de SQLAlchemy. Dado que en realidad no sé mucho acerca del funcionamiento interno SQLAlchemy, esto es lo que recomiendo:

class RecordData(object): 
    __slots__ = ('id', 'name', 'dirty') 

    def __init__(self, rec): 
     self.id = rec.id 
     self.name = rec.name 
     self.dirty = rec.dirty 

Luego, más tarde ...

def do_it(self): 
    records = self.query.filter(Record.dirty == True) 
    for record in records: 
     pass_to_other_process(RecordData(record)) 

Ahora, creo que hay una forma de saber SQLAlchemy para convertir su objeto en un objeto "tonto" que no tiene conexión con la base de datos y se parece mucho a lo que acabo de hacer aquí. Pero no sé lo que es.

+0

Usando una instancia independiente que no se hereda del 'declarative_base()' parece ser una buena solución , pero necesito tener dos clases casi idénticas, que creo que no es necesario. Tal vez encuentre una forma de usar la herencia múltiple (una vez desde su 'RecordData' y una vez desde' declarative_base() '). –

+0

@Manuel Faux: los objetos y las clases en Python son altamente mutables. Probablemente sea posible escribir algo que genere automáticamente la clase RecordData de la clase Record, especialmente si usaste los datos adicionales que SQLAlchemy agrega a la clase Record. Incluso podría almacenar esa clase como una variable de instancia de la clase Record para que no tenga que volver a generarla. – Omnifarious

10

Debe eliminar el objeto SQL ALchemy de la sesión aka 'expunge'. Luego puede solicitar cualquier atributo ya cargado sin intentar reutilizar su última sesión conocida/sesión no vinculada.

self.expunge(record) 

Tenga en cuenta que cualquier atributo descargado devolverá su último valor conocido o Ninguno. Si desea trabajar después con el objeto de nuevo sólo puede llamar a 'añadir' otra vez o 'fusión'

self.add(record) 
Cuestiones relacionadas