2017-04-02 149 views
1

我试图在特定的表上发生插入后执行一些操作。SAWarning:执行阶段当前不支持'Session.add()'操作的使用

user = ModelFactory.create_user(username, email, password) 
db.session.add(user) 
db.session.commit() 

所以我创建了一个自动调用after_insert的方法。

def notify_user(user): 
    print user.id 
    book = Book(author=user.id, name='foo') 
    db.session.add(book) 
    db.session.commit(book) 

@event.listens_for(User, 'after_insert') 
def receive_after_insert(mapper, connection, target): 
    print target 
    notify_user(target) 

但这代码显示的警告一样,

SAWarning: Usage of the 'Session.add()' operation is not currently supported within the execution stage of the flush process. Results may not be consistent. Consider using alternative event listeners or connection-level operations instead. 
    % method) 

/home/avinash/.virtualenvs/s2s/local/lib/python2.7/site-packages/sqlalchemy/util/langhelpers.py:68: SAWarning: An exception has occurred during handling of a previous exception. The previous exception is: 
<class 'sqlalchemy.exc.ResourceClosedError'> This transaction is closed 

This后显示,我们要做的before_flush工作。我试着移动before_flush方法中的逻辑,但它显示user.id是None。是的,这是预期的,因为实体不会被提交给db。

同样,我试过after_flush事件,但我仍然得到相同的警告。

回答

1

after_flush事件做工作:

@event.listens_for(User, "after_insert") 
def receive_after_insert(mapper, connection, user): 
    print(user.id) 
    @event.listens_for(Session, "after_flush", once=True) 
    def receive_after_flush(session, context): 
     session.add(Book(author=user.id, name="foo")) 

但是,为什么你不希望使User.author而不是有关系?

+0

在通知用户方法的开始处,我添加了db.session.flush(),它的工作原理是 –

+0

@AvinashRaj我觉得你没有充分发挥ORM的潜力。 ORM的一个主要特性是能够确定插入对象的顺序,以便能够填写外键。 – univerio

+0

你的意思是'db.session'是'Session'? –