Home > Back-end >  Alembic 1.8 DEFERRABLE INITIALLY IMMEDIATE
Alembic 1.8 DEFERRABLE INITIALLY IMMEDIATE

Time:06-15

I am now using Alembic 1.8, SQLAlchemy 1.4 and PostgreSQL

I would like to set my FK constraints as "DEFERRABLE INITIALLY IMMEDIATE".

I passed the FK options as shown below:

sa.Column(
    "group_id",
    sa.BigInteger,
    sa.ForeignKey(
        "auth_group.id",
        onupdate="CASCADE",
        ondelete="CASCADE",
        deferrable=True,
        initially="IMMEDIATE"
    ),
    index=True,
),

It generates my "create table" SQL like this:

    CONSTRAINT auth_user_groups_group_id_fkey FOREIGN KEY (group_id)
        REFERENCES public.auth_group (id) MATCH SIMPLE
        ON UPDATE CASCADE
        ON DELETE CASCADE,
        DEFERRABLE

I expected "DEFERRABLE INITIALLY IMMEDIATE" instead of "DEFERRABLE".

Please, let me know how to make the constraint as "DEFERRABLE INITIALLY IMMEDIATE".

Thank you.

CodePudding user response:

This is an issue (or design choice) of your DDL -> text generator -not with sqlalchemy.

The actual constraint information Postgres uses is stored in the table pg_catalog.pg_constraint. If you take a look at the docs for the pg_constraint table, you'll notice that the concept of deferability is (v7.2-v15 ) controlled entirely by the two boolean columns condeferrable and condeferred.

Thus, if a constraint is DEFERRABLE and it's not INITIALLY DEFERRED (checked end of transaction), it can only be INITIALLY IMMEDIATE (checked end of statement).

If you want to be absolutely certain, you can run this simple query:

SELECT
    pgc.conname constraint_name,
    pgc.confrelid::regclass tbl_name,
    CASE
      WHEN pgc.condeferrable
      THEN
        CASE
            WHEN pgc.condeferred
              THEN 'DEFERRABLE INITIALLY DEFERRED'
              ELSE 'DEFERRABLE INITIALLY IMMEDIATE'
            END
      ELSE 'NOT DEFERRABLE'
    END deferrability

FROM
    pg_catalog.pg_constraint pgc

WHERE
    conname = 'auth_user_groups_group_id_fkey'
  • Related