Skip to content

Alembic 1.10.4 incorrectly reflects nulls not distinct #1291

@CaselIT

Description

@CaselIT
          Hi, I'm not sure this is exactly related but might help.

We have updated to alembic 1.10.4 and we see some changes are always detected and not expected, everytime we generate a new migration.

-- requirements.txt

alembic==1.10.4
SQLAlchemy==2.0.19

-- models.py

from datetime import datetime

from sqlalchemy import UniqueConstraint
from sqlalchemy.orm import Mapped, mapped_column, DeclarativeBase

class Base(DeclarativeBase):
    pass

class Exemple(Base):
    __tablename__ = "dummy"
    id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True)
    a: Mapped[int]
    b: Mapped[int]
    tomb_date: Mapped[datetime] = mapped_column(nullable=True)
    __table_args__ = (
        UniqueConstraint(
            "a",
            "b",
            "tomb_date",
            postgresql_nulls_not_distinct=True,
            name="dummy_a_b_tomb_date_key"
        ),
    )

Initial migration is looking great, and postgresql nulls not distinct works.
But when I rerun autogenerate it always detect the same change.

alembic revision --autogenerate -m "test"
INFO  [alembic.runtime.migration] Context impl PostgresqlImpl.
INFO  [alembic.runtime.migration] Will assume transactional DDL.
INFO  [alembic.ddl.postgresql] Detected sequence named 'dummy_id_seq' as owned by integer column 'dummy(id)', assuming SERIAL and omitting
INFO  [alembic.autogenerate.compare] Detected changed unique constraint 'dummy_a_b_tomb_date_key' on 'dummy': expression ('UNIQUE_CONSTRAINT', 'a', 'b', 'tomb_date') to ('UNIQUE_CONSTRAINT', 'a', 'b', 'tomb_date', ('nulls_not_distinct', True))
  Generating ... /alembic/versions/733f639ec673_test.py ...  done

It generates a new migration file every time with the same content

"""test

Revision ID: 733f639ec673
Revises: a96502e5e7d3
Create Date: 2023-08-08 17:29:31.612196

"""
from typing import Sequence, Union

from alembic import op
import sqlalchemy as sa


# revision identifiers, used by Alembic.
revision: str = '733f639ec673'
down_revision: Union[str, None] = 'a96502e5e7d3'
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None


def upgrade() -> None:
    # ### commands auto generated by Alembic - please adjust! ###
    op.drop_constraint('dummy_a_b_tomb_date_key', 'dummy', type_='unique')
    op.create_unique_constraint('dummy_a_b_tomb_date_key', 'dummy', ['a', 'b', 'tomb_date'], postgresql_nulls_not_distinct=True)
    # ### end Alembic commands ###


def downgrade() -> None:
    # ### commands auto generated by Alembic - please adjust! ###
    op.drop_constraint('dummy_a_b_tomb_date_key', 'dummy', type_='unique')
    op.create_unique_constraint('dummy_a_b_tomb_date_key', 'dummy', ['a', 'b', 'tomb_date'])
    # ### end Alembic commands ###

Originally posted by @cedric-roussel in #1288 (comment)

Metadata

Metadata

Assignees

No one assigned

    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