Sqlalchemy事件`append`监听器导致UNIQUE约束失败

时间:2017-09-14 19:26:07

标签: python flask sqlalchemy flask-sqlalchemy

 class User(db.Model):
    __tablename__ = 'users'
    id = db.Column(db.Integer, primary_key=True)

class Paper(db.Model):
    __tablename__ = 'papers'
    id = db.Column(db.Integer, primary_key=True)
    reviewers = db.relationship('User', secondary=paper_reviewer,
                                backref=db.backref('papers_reviewed',
                                                   lazy='dynamic'),
                                lazy='dynamic')

paper_reviewer = db.Table('paper_reviewer',
                          db.Column('user_id', db.Integer,
                                    db.ForeignKey('users.id'),
                                    primary_key=True),
                          db.Column('paper_id', db.Integer,
                                    db.ForeignKey('papers.id'),
                                    primary_key=True)
                          )

@event.listens_for(Paper.reviewers, 'append')
def paper_reviewers_append(target, value, initiator):
    # db operation on other tables
    # target is paper obj
    print target.reviewers.all() # or other operation


paper.reviewers.append(usr)
db.session.add(paper)
db.session.commit()

在执行paper.reviewers.append(usr)之前触发了侦听器。 append的执行使两个插入到paper_reviewer表中。第二个导致IntegrityError: UNIQUE constraint failed

我在听众中尝试了不同的操作。如果操作触发了任何查询,则在执行commit()时会导致IntegrityError。

1 个答案:

答案 0 :(得分:0)

我引用谷歌小组成员的解决方案 “你可能会在你的听众中发生autoflush,所以请使用” session.no_autoflush“: http://docs.sqlalchemy.org/en/latest/orm/session_api.html?highlight=autocommit#sqlalchemy.orm.session.Session.no_autoflush

@event.listens_for(Paper.reviewers, 'append')
def paper_reviewers_append(target, value, initiator):
"""Update review preference."""
with db.session.no_autoflush:
    # db operation on other tables
    pass