我想在多个模型上执行验证。下面的文档说明可以通过Session.dirty
中的before_flush
免费访问属性。
但是,我的代码在Session is already flushing
中引发了before_flush
。
http://docs.sqlalchemy.org/en/rel_1_1/orm/session_events.html
经过多次尝试,我发现lazy='dynamic'
是其中一个原因,但其他视图需要延迟选项。
有没有人知道什么是错的?
from sqlalchemy import create_engine, event, Column, Integer, String, ForeignKey
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import relationship, sessionmaker
engine = create_engine('postgresql://dummy:dummy@127.0.0.1/dummy')
Base = declarative_base()
class Action(Base):
__tablename__ = 'actions'
id = Column(Integer, primary_key=True)
type = Column(String(30), nullable=False)
topic_id = Column(Integer, ForeignKey('topics.id'))
topic = relationship('Topic', back_populates='actions')
class Topic(Base):
__tablename__ = 'topics'
id = Column(Integer, primary_key=True)
name = Column(String(255), nullable=False)
actions = relationship('Action', back_populates='topic', lazy='dynamic')
Session = sessionmaker(bind=engine)
@event.listens_for(Session, 'before_flush')
def validate_before_flush(session, flush_context, instances):
for instance in session.dirty:
print(instance) # no problem(<__main__.Topic object at 0x7fa68165ecf8>)
print(instance.name) # no problem(modified)
print(instance.actions) # raise InvalidRequestError: Session is already flushing
session = Session()
topic = session.query(Topic).get(1)
topic.name = 'modified'
session.commit() # Execute before_flush and raise InvalidRequestError
答案 0 :(得分:0)
如果你有autoflush,那么SQLAlchemy将在从数据库查询任何内容之前尝试刷新(例如加载关系),但是当会话已经刷新时不支持刷新(例如在before_flush
挂钩中) ,所以你最终得到这个错误。尝试关闭autoflush:
Session = sessionmaker(bind=engine, autoflush=False)
请注意,如果您的应用程序被编写为依赖于该行为,则关闭autoflush可能(尽管很少)破坏您的应用程序。确保你了解关闭它的含义。