Skip to content

Commit de312d9

Browse files
committed
Make constraint queries schema-aware for multi-tenancy
Prior to this change, the ConstraintQueries class queried pg_catalog.pg_constraint without filtering by PostgreSQL schema. This caused incorrect behavior in multi-tenant environments using django-tenants, where each tenant has its own schema. The queries would detect constraints from other tenants' schemas, leading to false positives (e.g., ConstraintAlreadyExists errors when creating a second tenant). This change adds INNER JOINs with pg_catalog.pg_class and pg_catalog.pg_namespace to filter constraints by current_schema(). This ensures that constraint checks only look at the current tenant's schema, not across all schemas in the database. Affected queries: - CHECK_EXISTING_CONSTRAINT - CHECK_CONSTRAINT_IS_VALID - CHECK_CONSTRAINT_IS_NOT_VALID Related issue: #92
1 parent 5c2cbaf commit de312d9

File tree

2 files changed

+342
-171
lines changed

2 files changed

+342
-171
lines changed

src/django_pg_migration_tools/operations.py

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -53,25 +53,34 @@ class IndexQueries:
5353

5454
class ConstraintQueries:
5555
CHECK_EXISTING_CONSTRAINT = dedent("""
56-
SELECT conname
57-
FROM pg_catalog.pg_constraint
58-
WHERE conname = {constraint_name};
56+
SELECT con.conname
57+
FROM pg_catalog.pg_constraint con
58+
INNER JOIN pg_catalog.pg_class rel ON rel.oid = con.conrelid
59+
INNER JOIN pg_catalog.pg_namespace nsp ON nsp.oid = rel.relnamespace
60+
WHERE con.conname = {constraint_name}
61+
AND nsp.nspname = current_schema();
5962
""")
6063

6164
CHECK_CONSTRAINT_IS_VALID = dedent("""
6265
SELECT 1
63-
FROM pg_catalog.pg_constraint
66+
FROM pg_catalog.pg_constraint con
67+
INNER JOIN pg_catalog.pg_class rel ON rel.oid = con.conrelid
68+
INNER JOIN pg_catalog.pg_namespace nsp ON nsp.oid = rel.relnamespace
6469
WHERE
65-
conname = {constraint_name}
66-
AND convalidated IS TRUE;
70+
con.conname = {constraint_name}
71+
AND con.convalidated IS TRUE
72+
AND nsp.nspname = current_schema();
6773
""")
6874

6975
CHECK_CONSTRAINT_IS_NOT_VALID = dedent("""
7076
SELECT 1
71-
FROM pg_catalog.pg_constraint
77+
FROM pg_catalog.pg_constraint con
78+
INNER JOIN pg_catalog.pg_class rel ON rel.oid = con.conrelid
79+
INNER JOIN pg_catalog.pg_namespace nsp ON nsp.oid = rel.relnamespace
7280
WHERE
73-
conname = {constraint_name}
74-
AND convalidated IS FALSE;
81+
con.conname = {constraint_name}
82+
AND con.convalidated IS FALSE
83+
AND nsp.nspname = current_schema();
7584
""")
7685

7786
ALTER_TABLE_CONSTRAINT_NOT_NULL_NOT_VALID = dedent("""

0 commit comments

Comments
 (0)