Skip to content

1.20.0

Latest

Choose a tag to compare

@sqla-tester sqla-tester released this 11 Sep 19:09
· 2 commits to main since this release

1.20.0

Released: September 11, 2026

usecase

  • [usecase] [batch] Added a warning for the case where an unnamed CHECK constraint on a
    reflected table is omitted from a batch "recreate" operation. An unnamed
    CHECK constraint can't be reliably carried over in a batch recreate
    as it may refer to columns that are being dropped or changed. This
    omission was previously a silent operation. The presence of any
    ~sqlalchemy.schema.CheckConstraint in
    Operations.batch_alter_table.table_args is taken to indicate
    that the case has been accommodated, and no warning is emitted.

    References: #1846

  • [usecase] [autogenerate] Autogenerate now renders a warning comment above any rendered
    Operations.drop_constraint() directive for which the constraint name
    is None, as is the case when a constraint that has no name in the model
    is dropped, most typically within the downgrade() function of a
    migration that adds an unnamed constraint. A warning is also emitted on
    the console when the migration script is generated. The directive
    requires a non-None name in order to be able to emit a "DROP CONSTRAINT"
    command.

    References: #916

bug

  • [bug] [batch] Fixed bug in batch mode where adding a column with a type that generates
    its own CHECK constraint, such as ~sqlalchemy.types.Boolean or
    ~sqlalchemy.types.Enum with
    ~sqlalchemy.types.Boolean.create_constraint set to True,
    would emit the constraint twice when the table was recreated, once under
    the name generated by the naming convention in use and once under the
    name given to the type. The constraint is now emitted once, using the
    same name that would be used outside of batch mode.

    References: #1768

  • [bug] [batch] Fixed bug in batch mode where a CHECK constraint generated by a type such
    as ~sqlalchemy.types.Boolean or ~sqlalchemy.types.Enum
    would lose the name established for it by the naming convention in use
    when the table was recreated, as the constraint was regenerated against
    the temporary table used for the recreate operation. The naming
    convention is now resolved against the name of the table being replaced.

    As part of this change, a type that generates a CHECK constraint but has
    no name of its own, used in conjunction with a naming convention that
    includes the %(constraint_name)s token, now emits a warning, as the
    convention has no name to interpolate; the constraint continues to be
    emitted without a name. As noted at batch_check_constraints,
    these datatypes should be given a name in order to participate fully in
    batch mode.

    References: #1844

  • [bug] [batch] Fixed bug in batch mode where the
    Operations.batch_alter_table.naming_convention parameter
    would re-generate the names of constraints that already had a name when
    reflected, in the case where the convention included the
    %(constraint_name)s token, leading to a name that included the
    convention's own prefix twice. The convention is now applied only to
    those constraints that are reflected without a name, which is the use
    case the parameter is documented for.

    References: #1845

  • [bug] [mysql] Fixed bug where autogenerate with
    EnvironmentContext.configure.compare_server_default would
    report a persistent server default change for Float, Numeric and
    other decimal columns on MySQL. MySQL reports a literal server default
    for such a column either in quoted form, e.g. '1', or, when the
    value is fractional, as a parenthesized expression, e.g. (2.5);
    neither form was accommodated for columns other than those of
    Integer affinity, so that a default such as server_default="1"
    on a sqlalchemy.Float column would never compare as equal to
    the reflected value.

    References: #1866

  • [bug] [mysql] Fixed bug where autogenerate with
    EnvironmentContext.configure.compare_server_default would
    report a persistent server default change for an expression server
    default such as (rand()). MySQL reports such a default with the
    surrounding parenthesis included whereas MariaDB reports it without
    them, so that the parenthesis are now disregarded when comparing.

    References: #1866

misc

  • [change] [general] Support for SQLAlchemy 1.4 is dropped as of Alembic 1.20.0; SQLAlchemy
    2.0.0 is now the minimum required version. SQLAlchemy 1.4 has no support
    for Python 3.13 and above, and the version-conditional code paths it
    required throughout Alembic have been removed in favor of the SQLAlchemy
    2.0 API.

    References: #1851