问题描述
我正在使用---------------------------------------------------------------------------
NameError Traceback (most recent call last)
<ipython-input-20-8909d368129a> in <module>()
12
13 m=1
---> 14 if u>v:
15 m=m+1
16 else:
NameError: name 'u' is not defined
表中名为valid_period
的带有日期范围字段的postgres。
我用来添加约束的查询
thing_thing
这很好。
- 具有相同
CREATE EXTENSION IF NOT EXISTS btree_gist; ALTER TABLE thing_thing ADD CONSTRAINT prevent_overlapping_valid_periods_by_team EXCLUDE USING gist(team_id WITH =,valid_period WITH &&) DEFERRABLE INITIALLY DEFERRED;
且重叠team_id
=>的行被阻止? - 具有不同的
valid_period
和重叠的team_id
=>的行✅ - 具有相同
valid_period
并且不重叠team_id
=>的行row
我需要什么但不确定如何做
但是我只希望约束在IF中发挥作用
- 字段
valid_period
(布尔字段)也是false或 - 字段
is_removed
(varchar字段)包含任何可能的值之一,例如state
,CANCELLED
因此以下操作无效:
- 具有相同的
REJECTED
和重叠的team_id
但行valid_period
为True的行=>预期允许✅但被阻止? - 具有相同的
is_removed
和重叠的team_id
但行valid_period
为state
的行=>预期允许✅但被阻止? - 具有相同的
CANCELLED
和重叠的team_id
但行valid_period
为state
的行=>预期允许✅但被阻止?
如何更改约束以允许例外?换句话说,有点像局部唯一索引。
的部分约束但是同时,我认为无法使用部分唯一索引来防止非法重叠的日期范围。
解决方法
您可以对此使用部分索引-至少在PostgreSQL v13中可以使用-尚未检查其他索引。
请注意括号WHERE
上的内容-如果您忘记了括号,则会发出抗议。
下面的示例与您的描述相比有所简化,但在逻辑上是相同的。
=> CREATE TABLE teams (team_id int not null,valid_period daterange not null,is_removed boolean not null,state char not null);
=> ALTER TABLE teams ADD CONSTRAINT no_overlaps
EXCLUDE USING gist(team_id WITH =,valid_period WITH &&)
WHERE (is_removed = false OR state IN ('C','R'));
=> INSERT INTO teams VALUES (1,daterange('2020-01-01','2021-01-01'),false,'X');
INSERT 0 1
=> INSERT INTO teams VALUES (1,'X');
ERROR: conflicting key value violates exclusion constraint "no_overlaps"
DETAIL: Key (team_id,valid_period)=(1,[2020-01-01,2021-01-01)) conflicts with existing key (team_id,2021-01-01)).
=> INSERT INTO teams VALUES (1,true,'C');
ERROR: conflicting key value violates exclusion constraint "no_overlaps"
DETAIL: Key (team_id,2021-01-01)).