In Postgres, I am trying to find a way to enforce a special kind of constraint across two columns.
I have a table with this schema (the relevant bits):
CREATE TABLE resources (
id SERIAL PRIMARY KEY,
org_id INT NOT NULL,
source_id INT NOT NULL,
data JSON NOT NULL -- to keep it simple, it could be anything
);
Some example data:
id | org_id | source_id | data
---------------------------------------
1 | 11 | 1001 | {...}
2 | 22 | 2002 | {...}
3 | 33 | 3003 | {...}
4 | 11 | 1001 | {...}
5 | 11 | 2002 | {...} -- This should be invalid.
Assuming the data
value of all rows is different, both rows 1
and 4
are valid. They're just different resources linked to the same org_id
and source_id
.
However, I never want a source_id
to be used with different org_id
s. In the example above, row 5
should be invalid because source_id = 2002
was already used once with org_id = 22
, and it should not be possible to use it again with org_id = 11
.
I know how to achieve this in a query, but it either requires locking, or it requires a multi-step process in application code (which wouldn't be the end of the world). I thought it could be done with an EXCLUDE
constraint, but I'm not sure.