【问题标题】:How to automatically add a SQLAlchemy object to the session?如何自动将 SQLAlchemy 对象添加到会话中?
【发布时间】:2012-03-26 13:42:14
【问题描述】:

我有一个使用声明方法创建的 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) 可以做到这一点,所以在某种意义上它一定是可能的。

【问题讨论】:

    标签: python sqlalchemy


    【解决方案1】:

    超级简单。使用事件:

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

    【讨论】:

    • 请注意,如果您使用 SQLAlchemy 验证或预刷新事件,您还必须从会话中删除验证失败的对象。使用此解决方案时,我只是对此有所了解。
    猜你喜欢
    • 2016-05-03
    • 2014-08-09
    • 2012-04-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-17
    • 1970-01-01
    相关资源
    最近更新 更多