加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Python > 正文

如何在SQLALchemy Core中“设置CONSTRAINTS … DEFERRED”

发布时间:2020-12-20 13:53:01 所属栏目:Python 来源:网络整理
导读:我正在使用SQLAlchemy和PostgreSQL. Postgres支持执行延迟约束,这允许我们推迟检查表上的约束,直到事务结束. 例如,在SQLAlchemy中,我可能会定义一个这样的表: t_group_categories = Table('group_categories',metadata,Column('id',Integer,primary_key=Tru
我正在使用SQLAlchemy和PostgreSQL. Postgres支持执行延迟约束,这允许我们推迟检查表上的约束,直到事务结束.

例如,在SQLAlchemy中,我可能会定义一个这样的表:

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

SQLAlchemy会生成一个CREATE TABLE语句,它看起来像:

CREATE TABLE group_categories
(
  id serial NOT NULL,group_id integer,CONSTRAINT group_categories_pkey PRIMARY KEY (id),CONSTRAINT group_categories_group_id_fkey FOREIGN KEY (group_id)
      REFERENCES groups (id) MATCH SIMPLE
      ON UPDATE NO ACTION ON DELETE CASCADE DEFERRABLE INITIALLY IMMEDIATE
)

根据我的理解,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”)似乎也没有任何效果;我仍然遇到IntegrityError.
>在事务块内执行connection.execute(“SET CONSTRAINTS group_categories_group_id_fkey DEFERRED”)也会返回IntegrityError.

解决方法

如 this question中所述,外键约束 can’t be deferred,即使它们被声明为:

Referential actions other than the NO ACTION check cannot be deferred,even if the constraint is declared deferrable.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读