微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在 Postgres 中跨表应用的非唯一约束名称

如何解决在 Postgres 中跨表应用的非唯一约束名称

通过 sqlAlchemy 和 Alembic,我创建了一些共享名称但在其他方面相互独立的表约束。这会产生一些令人惊讶的结果,其中约束检查应用于与约束规范不匹配的表中的列。

可重现的例子:

DROP TABLE IF EXISTS users;

CREATE TABLE users (
    id UUID DEFAULT uuid_generate_v4() NOT NULL,created_at TIMESTAMP WITHOUT TIME ZONE NOT NULL,updated_at TIMESTAMP WITHOUT TIME ZONE NOT NULL,join_date DATE,userrole VARCHAR(19) NOT NULL,status VARCHAR(24) NOT NULL,PRIMARY KEY (id),CONSTRAINT role CHECK (userrole IN ('standard','admin','readonly'))
);

DROP TABLE IF EXISTS groups;

CREATE TABLE groups (
    id UUID DEFAULT uuid_generate_v4() NOT NULL,grouprole VARCHAR(19) NOT NULL,CONSTRAINT role CHECK (grouprole IN ('foo','bar','baz'))
);

users 表中的检查将约束应用于 usersgroups 表中的列。同样,groups 表中的检查将约束应用于 groups users 表中的列。

检查在表之间交叉的地方,它应用于索引处的列,您希望它应用于定义它的表中。上面的例子结果如下:

用户

姓名 类型 可以为空 检查
1 id uuid 没有 NULL uuid_generate_v4()
2 created_at 时间戳 没有 (role)::text = ANY ((ARRAY['foo'::character 变化,'bar'::character 变化,'baz'::character 变化])::text[]) NULL
3 updated_at 时间戳 没有 NULL NULL
4 加入日期 日期 NULL NULL
5 用户角色 varchar(19) 没有 (role)::text = ANY ((ARRAY['standard'::character 可变,'admin'::character 可变,'readonly'::character 可变])::text[]) NULL
6 状态 varchar(24) 没有 NULL NULL

组:

姓名 类型 可以为空 检查
1 id uuid 没有 NULL uuid_generate_v4()
2 组角色 varchar(19) 没有 (role)::text = ANY ((ARRAY['foo'::character 变化,'bar'::character 变化,'baz'::character 变化])::text[]) NULL
3 created_at 时间戳 没有 NULL NULL
4 updated_at 时间戳 没有 NULL NULL
5 状态 varchar(24) 没有 (role)::text = ANY ((ARRAY['standard'::character 可变,'admin'::character 可变,'readonly'::character 可变])::text[]) NULL

更改约束之一的名称足以解决此问题。这是约束应该起作用的方式吗?

我创建了一个 DB Fiddle显示它适用于多个 Postgres 版本。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。