2012-03-26 19 views
5

que tienen una clase de mesa SQLAlchemy creado usando el método declarativo:¿Cómo agregar automáticamente un objeto SQLAlchemy a la sesión?

mysqlengine = create_engine(dsn) 
session = scoped_session(sessionmaker(bind=mysqlengine)) 
Base = declarative_base() 
Base.metadata.bind = mysqlengine 

class MyTable(Base): 
    __table_args__ = {'autoload' : True} 

Ahora, cuando se utiliza esta tabla dentro del código me gustaría no tener que utilizar el session.add método con el fin de agregar cada nuevo registro a la sesión activa así que en vez de:

row = MyTable(1, 2, 3) 
session.add(row) 
session.commit() 

me gustaría tener:

row = MyTable(1, 2, 3) 
session.commit() 

Ahora, sé que de esta pregunta ya: Possible to add an object to SQLAlchemy session without explicit session.add()?

Y, me di cuenta que se puede obligar a este comportamiento de la siguiente manera:

class MyTable(Base): 
    def __init__(self, *args, **kw): 
    super(MyTable, self).__init__(*args, **kw) 
    session.add(self) 

Sin embargo, no quiero a inflar mi código que contiene 30 cuadros con este método. También sé que Elixir (http://elixir.ematia.de/trac/wiki) hace esto, por lo que debe ser posible en cierto sentido.

Respuesta

15

Super simple. Utilice un evento:

from sqlalchemy import event, Integer, Column, String 
from sqlalchemy.orm import scoped_session, sessionmaker, mapper 
from sqlalchemy.ext.declarative import declarative_base 

Session = scoped_session(sessionmaker()) 

@event.listens_for(mapper, 'init') 
def auto_add(target, args, kwargs): 
    Session.add(target) 

Base = declarative_base() 

class A(Base): 
    __tablename__ = "a" 

    id = Column(Integer, primary_key=True) 
    data = Column(String) 

a1 = A(data="foo") 
assert a1 in Session() 
+1

Sólo ten en cuenta que si usted está utilizando la validación SQLAlchemy o eventos pre-ras, también hay que borrar de la sesión de un objeto que falla la validación. Me acabo de pegar cuando uso esta solución. –

Cuestiones relacionadas