如何设置约束。。。延迟`in SQLALchemy C

2024-09-25 08:40:11 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在使用SQLAlchemy和PostgreSQL。Postgres支持执行延迟约束,这允许我们将对表的约束的检查推迟到事务结束。在

例如,在SQLAlchemy中,我可能会定义如下表:

t_group_categories = Table('group_categories', metadata,
    Column('id', Integer, primary_key=True),
    Column('group_id', Integer, ForeignKey('groups.id', deferrable=True))
)

SQLAlchemy将生成一个CREATE TABLE语句,该语句如下所示:

^{pr2}$

据我所知,DEFERRABLE INITIALLY IMMEDIATE意味着FOREIGN KEY约束 将表现为它是一个不可延迟的约束,除非显式地告诉它 否则,这正是我想要的。在

问题是我似乎找不到任何关于如何让SQLAlchemy核心在事务内部实际发出SET CONSTRAINTS ... DEFERRED命令的信息。 例如,假设我有以下代码:

connection = engine.connect()
...
with connection.begin() as transaction:
    # Create a group
    r = connection.execute(
        t_groups.insert().values(...)
    )
    group_id = r.inserted_primary_key

    # Assign a category to the group (ERROR!)
    r2 = connection.execute(
        t_group_categories.insert().values(group_id=group_id, ...)
    )

第一个块只是创建一个新组。然后,第二个块尝试分配组 我们刚刚创建了一个类别。问题是如果没有特殊的SET CONSTRAINTS ... DEFERRED, 我们实际上无法在不违反外键约束的情况下创建group_categories条目 因为交易还没有提交。在

在这个实例中,我想做的是将检查约束推迟到事务提交之后。 如何将约束检查推迟到事务完成之后?在


注意事项:

  • 问题在 How to SET CONSTRAINTS DEFERRED in sqlalchemy expression language?与之类似,但是OP对使用DEFERRABLE INITIALLY DEFERRED感兴趣,我不希望这样做。相反(如果可能),我希望将我的约束保留为DEFERRABLE INITIALLY IMMEDIATE,并显式地标记需要延迟约束的实例。在
  • SQLAlchemy生成了DEFERRABLE INITIALLY DEFERRED约束,因此我希望/假设它有一种在另一端实际使用该约束的表达方式(即发出SET CONSTRAINTS ... DEFERRED的表达式语言方式)。在

更新:

  • connection.execute("SET CONSTRAINTS ALL DEFERRED")似乎也没有任何效果;我仍然得到一个完整性错误。在
  • 在事务块中执行connection.execute("SET CONSTRAINTS group_categories_group_id_fkey DEFERRED")操作也会返回IntegrityError。在

Tags: idexecutesqlalchemygroupcolumnintegerconnection事务