我正在使用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
语句,该语句如下所示:
据我所知,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
条目
因为交易还没有提交。在
在这个实例中,我想做的是将检查约束推迟到事务提交之后。 如何将约束检查推迟到事务完成之后?在
注意事项:
DEFERRABLE INITIALLY DEFERRED
感兴趣,我不希望这样做。相反(如果可能),我希望将我的约束保留为DEFERRABLE INITIALLY IMMEDIATE
,并显式地标记需要延迟约束的实例。在DEFERRABLE INITIALLY DEFERRED
约束,因此我希望/假设它有一种在另一端实际使用该约束的表达方式(即发出SET CONSTRAINTS ... DEFERRED
的表达式语言方式)。在更新:
connection.execute("SET CONSTRAINTS ALL DEFERRED")
似乎也没有任何效果;我仍然得到一个完整性错误。在connection.execute("SET CONSTRAINTS group_categories_group_id_fkey DEFERRED")
操作也会返回IntegrityError。在
目前没有回答
相关问题 更多 >
编程相关推荐