Как автоматически добавить объект SQLAlchemy в сеанс? - PullRequest
5 голосов
/ 26 марта 2012

У меня есть класс таблицы SQLAlchemy, созданный с использованием метода декларативного:

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

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

Теперь, когда я использую эту таблицу в коде, я бы не хотел использовать session.add метод для добавления каждой новой записи в активный сеанс, поэтому вместо:

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

я хотел бы иметь:

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

Теперь я уже знаю этот вопрос: Возможно добавить объект в сеанс SQLAlchemy без явного session.add ()?

И я понимаю, что вы можете вызвать это поведение, выполнив следующее:

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

Тем не менее, я не хочу использовать этот метод в своем коде, содержащем 30 таблиц.Я также знаю, что Эликсир (http://elixir.ematia.de/trac/wiki) делает это, поэтому в некотором смысле это должно быть возможно.

1 Ответ

15 голосов
/ 26 марта 2012

Супер просто. Использовать событие:

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()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...