SQLAlchemy ORM - 推迟约束检查

5
我有一张表上的独特限制需要延迟,Postgresql支持这个功能,但是我无法在SQLAlchemy ORM中找到设置选项(不仅仅是针对这种情况)。我使用了bulk_update_mappings()函数,该限制出现在__table_args__的第二个参数下。是否需要使用SQLAlchemy Core或创建自己的SQL语句来实现此功能?
class Question(Base):
    QuestionType = enum.Enum('QuestionType', 'mcq')
    __tablename__ = 'questions'
    id = Column(Integer, primary_key=True)
    type = Column(Enum(_QuestionType), nullable=False)
    description = Column(String, nullable=False)
    question_order = Column(Integer, nullable=False)
    question_set_id = Column(Integer, ForeignKey('question_sets.id', ondelete='cascade'), nullable=False)

    question_set = relationship('QuestionSet', back_populates='questions')

    __table_args__ = (
        UniqueConstraint('question_set_id', 'description'),
        UniqueConstraint('question_set_id', 'question_order', deferrable=True)
    )
    __mapper_args__ = {
        'polymorphic_identity': 'question',
        'polymorphic_on': type,
    }

#from another class
def reorder(self, new_order, db):
    order = [{'id':i, 'question_order': index} for index, i in enumerate(new_order)]
    db.bulk_update_mappings(Question, order)
    db.commit()

1
在进行批量操作之前,请运行db.execute('SET CONSTRAINTS ALL DEFERRED')以推迟当前事务中的所有可推迟约束:https://www.postgresql.org/docs/current/static/sql-set-constraints.html。如果您知道唯一约束的名称,可以选择仅推迟唯一约束。 - Ilja Everilä
这个可以。我给我的约束命名,并执行了 db.execute('SET CONSTRAINTS unique_order DEFERRED;') - nav
相关,但不是重复:https://dev59.com/2o_ea4cB1Zd3GeqPIwjA,https://stackoverflow.com/questions/14210453/how-to-set-constraints-deferred-in-sqlalchemy-expression-language - Ilja Everilä
1个回答

6

假设 db 是您的会话实例,请运行以下命令:

db.execute('SET CONSTRAINTS ALL DEFERRED')

在进行批量操作之前,在当前事务中以延迟所有可延迟约束。请注意,并非所有约束都可延迟,即使它们被声明为可延迟的。如果您知道其名称,可以仅延迟唯一约束,例如unique_order

def reorder(self, new_order, db):
    order = [{'id':i, 'question_order': index} for index, i in enumerate(new_order)]
    db.execute('SET CONSTRAINTS unique_order DEFERRED')
    db.bulk_update_mappings(Question, order)
    db.commit()

在批量操作之后,是否需要执行 SET CONSTRAINTS ALL IMMEDIATE?或者这会在 commit() 之后自动发生? - Jean Monet
1
"SET CONSTRAINTS" 控制事务中的约束,在提交之后其效果将消失。 - Ilja Everilä

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接