2012-03-26 17 views
5

Mam klasy tabeli SQLAlchemy utworzony za pomocą deklaratywnej metody:Jak automatycznie dodać obiekt SQLAlchemy do sesji?

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

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

Teraz, przy użyciu tej tabeli w kodzie Chciałbym nie trzeba używać session.add metodę, aby dodać każdy nowy rekord do aktywnej sesji więc zamiast:

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

chciałbym posiadać:

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

Wiem, że to pytanie już: Possible to add an object to SQLAlchemy session without explicit session.add()?

I zdaję sobie sprawę, można wymusić to zachowanie, wykonując następujące czynności:

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

Ja jednak nie chcę uwędzić mój kod zawierający 30 tabele Ta metoda. Wiem też, że Elixir (http://elixir.ematia.de/trac/wiki) robi to, więc musi być możliwe w pewnym sensie.

Odpowiedz

15

Super proste. Użyj zdarzenie:

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

Wystarczy mieć świadomość, że jeśli używasz walidacji sqlalchemy lub zdarzenia pre-flush, trzeba także wykreślić z sesji do obiektu, który nie powiedzie walidacji. Po prostu przyszło mi to do głowy przy korzystaniu z tego rozwiązania. –

Powiązane problemy