如何自动将SQLAlchemy对象添加到会话?

时间:2012-03-26 13:42:14

标签: python sqlalchemy

我有一个使用Declarative方法创建的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()

现在,我已经知道了这个问题:Possible to add an object to SQLAlchemy session without explicit session.add()?

并且,我意识到您可以通过执行以下操作来强制执行此操作:

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

但是,我不希望使用此方法膨胀包含30个表的代码。我也知道Elixir(http://elixir.ematia.de/trac/wiki)这样做,所以在某种意义上它必须是可能的。

1 个答案:

答案 0 :(得分:15)

超级简单。使用活动:

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()