Skip to content

Constraint queries not schema-aware in multi-tenant environments #92

@RJPercival

Description

@RJPercival

Description

The ConstraintQueries class contains three SQL queries that check for constraint existence and validity, but they don't filter by PostgreSQL schema. This causes incorrect behavior in multi-tenant environments using django-tenants, where each tenant has its own schema.

Impact

When creating a second tenant in a django-tenants setup, migrations fail with ConstraintAlreadyExists errors because the queries detect constraints from the first tenant's schema instead of only checking the current tenant's schema.

Affected Queries

  1. CHECK_EXISTING_CONSTRAINT
  2. CHECK_CONSTRAINT_IS_VALID
  3. CHECK_CONSTRAINT_IS_NOT_VALID

All three queries in ConstraintQueries query pg_catalog.pg_constraint but don't join with pg_namespace to filter by current_schema().

Example Error

django_pg_migration_tools.operations.ConstraintAlreadyExists: Cannot create a constraint with the name unique_identity_provider_uuid because a constraint of the same name already exists.

This occurs even though the constraint doesn't exist in the current tenant's schema - it only exists in another tenant's schema.

Proposed Fix

Join with pg_class and pg_namespace to filter by the current schema:

SELECT con.conname
FROM pg_catalog.pg_constraint con
INNER JOIN pg_catalog.pg_class rel ON rel.oid = con.conrelid
INNER JOIN pg_catalog.pg_namespace nsp ON nsp.oid = rel.relnamespace
WHERE con.conname = {constraint_name} AND nsp.nspname = current_schema();

Similar changes needed for the other two queries.

Context

This issue was discovered when migrating kraken-core to use django-tenants for multi-tenancy. The same issue was found and fixed in kraken-core's own migration utilities.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions