Skip to content

Migration default_schema: caller-contract is implicit; should normalize identifiers per dialect #478

@cofin

Description

@cofin

Summary

PR #471 (feat/migration-default-schema) adds first-class support for migration_config["default_schema"]. The hooks (set_migration_session_schema, has_schema) currently expect the caller to pass the literal stored identifier:

  • Oracle: pass "TENANT" (or the exact case for users created with quoted identifiers).
  • PostgreSQL family / DuckDB / ADBC PG: pass the lowercase form for unquoted-created schemas.

This is documented in docs/usage/migrations.rst, but the contract is undiscoverable from the code. A user who configures default_schema="myapp" against an Oracle database with user MYAPP will hit MigrationError: Configured schema 'myapp' does not exist even though the schema is right there.

Why this is a follow-up, not a blocker

The implicit-contract behavior matches the existing data-dictionary contract (see #477). Fixing it in the migration layer alone would diverge the two layers — the proper fix folds in there. This issue exists to track that once #477 lands, the migration hooks should adopt the same normalizers so users can pass any case form.

Concrete asks

Once per-dialect normalizers exist (see #477):

  • set_migration_session_schema(schema) normalizes before quoting/interpolating.
  • has_schema(schema) normalizes before binding.
  • Update docs to drop the "pass the literal stored identifier" guidance.

Scope

Small once the normalizer infrastructure exists. ~5 adapter drivers (asyncpg, psycopg, psqlpy, adbc-PG, oracledb). DuckDB is case-insensitive by default; no normalization needed.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions