Releases: sqlalchemy/alembic
Release list
1.19.0
1.19.0
Released: August 4, 2026
changed
-
[changed] [installation] Environmental updates:
- Trove classifiers now include Python 3.15 which is now part of CI integration - Python 3.14 is also added to trove classifiers which had been previously omitted - Implemented [PEP 604](https://peps.python.org/pep-0604) style unions in type annotations
feature
-
[feature] [autogenerate] Autogenerate now detects the addition and removal of named CHECK
constraints, as part of the default autogenerate behavior. Detection is
name-based only; a constraint whose name is unchanged is presumed
equivalent regardless of its expression text, as reliably normalizing
SQL expressions across backends for comparison purposes is not generally
feasible. This behavior is implemented as a plugin named
alembic.autogenerate.checkconstraint_byname, and may be disabled if not
desired by excluding it from the
EnvironmentContext.configure.autogenerate_pluginslist.
Pull request courtesy Francois van Kempen.References: #508
bug
-
[bug] [commands] Fixed inconsistency where running
stampordowngradetobasein
offline (--sql) mode would emit aDROP TABLE alembic_version
statement, while the same operations in online mode never drop the version
table. Offline mode no longer emits thisDROP, matching online
behavior. The version table continues to be created when it does not exist;
only the spurious offline-only drop has been removed. Pull request
courtesy imurodl.References: #1822
1.18.5
1.18.5
Released: June 25, 2026
usecase
-
[usecase] [commands] Added
--splicesupport to themerge()command. Previously, the
merge command would suggest using--splicewhen attempting to merge
non-head revisions, but the flag was not actually accepted by the command.
Thespliceparameter is now available in both the command-line
interface and thecommand.merge()function, matching the existing
support incommand.revision(). Pull request courtesy Kadir Can
Ozden.References: #1712
-
[usecase] [environment] Added
ScriptDirectory.get_heads.consider_depends_on
parameter toScriptDirectory.get_heads(). When set toTrue,
head revisions that are also a dependency of another revision via
depends_onare excluded from the result, matching the effective
heads that would be present in thealembic_versiontable after
running all upgrades.References: #1806
bug
-
[bug] [autogenerate] Fixed rendering of dialect keyword arguments containing
~sqlalchemy.schema.Columnobjects within sequences, such as
postgresql_include. These were previously rendered usingrepr(),
producing invalid Python in the generated migration scripts. Column
objects within list or tuple values are now correctly rendered as their
string column names. Pull request courtesy Ajay Singh.References: #1258
-
[bug] [mysql] Implemented type comparison for
ENUMdatatypes on MySQL, which
checks that the individual enum values are equivalent. If additional
entries are on either side, this generates a diff. Changes of order do not
generate a diff. Pull request courtesy Furkan KΓΆykΔ±ran. -
[bug] [operations] Fixed bug where the
inline_referencesparameter of
Operations.add_column()did not include foreign key referential
actions such asON DELETE,ON UPDATE,DEFERRABLE,
INITIALLY, andMATCHwhen rendering the inlineREFERENCES
clause.References: #1820
1.18.4
1.18.4
Released: February 10, 2026
bug
-
[bug] [operations] Reverted the behavior of
Operations.add_column()that would
automatically render the "PRIMARY KEY" keyword inline when a
Columnwithprimary_key=Trueis added. The automatic
behavior, added in version 1.18.2, is now opt-in via the new
Operations.add_column.inline_primary_keyparameter. This
change restores the ability to render a PostgreSQL SERIAL column, which is
required to beprimary_key=True, while not impacting the ability to
render a separate primary key constraint. This also provides consistency
with theOperations.add_column.inline_referencesparameter and
gives users explicit control over SQL generation.To render PRIMARY KEY inline, use the
Operations.add_column.inline_primary_keyparameter set to
True:op.add_column(
"my_table",
Column("id", Integer, primary_key=True),
inline_primary_key=True
)References: #1232
1.18.3
1.18.3
Released: January 29, 2026
bug
-
[bug] [autogenerate] Fixed regression in version 1.18.0 due to #1771 where autogenerate
would raiseNoReferencedTableErrorwhen a foreign key constraint
referenced a table that was not part of the initial table load, including
tables filtered out by the
EnvironmentContext.configure.include_namecallable or tables
in remote schemas that were not included in the initial reflection run.The change in #1771 was a performance optimization that eliminated
additional reflection queries for tables that were only referenced by
foreign keys but not explicitly included in the main reflection run.
However, this optimization inadvertently removed the creation of
Tableobjects for these referenced tables, causing autogenerate
to fail when processing foreign key constraints that pointed to them.The fix creates placeholder
Tableobjects for foreign key targets
that are not reflected, allowing the autogenerate comparison to proceed
without error while maintaining the performance improvement from
#1771. When multiple foreign keys reference different columns in
the same filtered table, the placeholder table accumulates all necessary
columns. These placeholder tables may be visible when using the
EnvironmentContext.configure.include_objectcallable to
inspectForeignKeyConstraintobjects; they will have the name,
schema and basic column information for the relevant columns present.References: #1787
-
[bug] [general] Fixed regression caused by #1669 which requires SQLAlchemy objects
to support generic type subscripting; for the older SQLAlchemy 1.4 series,
this requires version 1.4.23. Changed the minimum requirements to require
version 1.4.23 rather than 1.4.0.References: #1788
1.18.2
1.18.2
Released: January 28, 2026
usecase
-
[usecase] [operations] The
primary_keyparameter onColumnis now honored when
Operations.add_column()is used, and will emit the "PRIMARY KEY"
keyword inline within the ADD COLUMN directive. This is strictly a syntax
enhancement; no attempt is made to reconcile the column's primary key
status with any existing primary key constraint or particular backend
limitations on adding columns to the primary key.References: #1232
-
[usecase] [operations] Added
inline_referencesparameter toOperations.add_column()
which allows rendering ofREFERENCESclauses inline within theADD COLUMNdirective rather than as a separateADD CONSTRAINTdirective.
This syntax is supported by PostgreSQL, Oracle, MySQL 5.7+, and MariaDB
10.5+, and can provide performance benefits on large tables by avoiding
full table validation when adding a nullable foreign key column.References: #1780
bug
-
[bug] [typing] Fixed typing issue where the
AlterColumnOp.server_defaultand
AlterColumnOp.existing_server_defaultparameters failed to
accommodate common SQLAlchemy SQL constructs such asnull()and
text(). Pull request courtesy Sebastian Kreft.References: #1669
1.18.1
1.18.1
Released: January 14, 2026
bug
-
[bug] [autogenerate] Fixed issue in new plugin system where the configured logger was not
correctly using the__name__token to identify the logger.References: #1779
-
[bug] [operations] Revised the change regarding SQLAlchemy 2.1 and deprecation warnings
related toisolate_from_table=True. Further developments in release 2.1
have revised how this parameter will be modified.
1.18.0
1.18.0
Released: January 9, 2026
feature
-
[feature] [operations] When alembic is run in "verbose" mode, alembic now logs a message to
indicate from which file is used to load the configuration.References: #1737
-
[feature] [autogenerate] Autogenerate reflection sweeps now use the "bulk" inspector methods
introduced in SQLAlchemy 2.0, which for selected dialects including
PostgreSQL and Oracle use batched queries to reflect whole collections of
tables using O(1) queries rather than O(N).References: #1771
-
[feature] [autogenerate] Release 1.18.0 introduces a plugin system that allows for automatic
loading of third-party extensions as well as configurable autogenerate
compare functionality on a per-environment basis.The
Pluginclass provides a common interface for extensions that
register handlers among Alembic's existing extension points such as
Operations.register_operation()and
Operations.implementation_for(). A new interface for registering
autogenerate comparison handlers,
Plugin.add_autogenerate_comparator(), provides for autogenerate
compare functionality that may be custom-configured on a per-environment
basis using the new
EnvironmentContext.configure.autogenerate_pluginsparameter.The change does not impact well known Alembic add-ons such as
alembic-utils, which continue to work as before; however, such add-ons
have the option to provide plugin entrypoints going forward.As part of this change, Alembic's autogenerate compare functionality is
reorganized into a series of internal plugins under the
alembic.autogeneratenamespace, which may be individually or
collectively identified for inclusion and/or exclusion within the
EnvironmentContext.configure()call using a new parameter
EnvironmentContext.configure.autogenerate_plugins. This
parameter is also where third party comparison plugins may also be
indicated.See
alembic.plugins.toplevelfor complete documentation on
the newPluginclass as well as autogenerate-specific usage
instructions.
usecase
-
[usecase] [environment] The
file_templateconfiguration option now supports directory paths,
allowing migration files to be organized into subdirectories. When using
directory separators infile_template(e.g.,
%(year)d/%(month).2d/%(day).2d_%(rev)s_%(slug)s), Alembic will
automatically create the necessary directory structure. The
recursive_version_locationssetting must be set totruewhen using
this feature in order for the revision files to be located for subsequent
commands.References: #1774
-
[usecase] Avoid deprecation warning in add/drop constraint added in SQLAlchemy 2.1.
Ensure that alembic is compatible with the changes added in
sqlalchemy/sqlalchemy#13006
by explicitly settingisolate_from_table=Truewhen running with
SQLAlchemy 2.1 or greater.
bug
-
[bug] [postgresql] Fixed issue where PostgreSQL sequence defaults on non-primary key columns
were incorrectly detected as changed on every autogenerate run. Server
default comparison logic is adjusted to filter out the::regclass
expression added by the server which interferes with the comparison.References: #1507
-
[bug] [mssql] Implemented DDL for column comment add/update/delete when using the
Operations.alter_column.commentparameter with
Operations.alter_column()on Microsoft SQL Server. Previously,
these functions were not implemented for SQL Server and would raise
UnsupportedCompilationError.References: #1755
1.17.2
1.17.2
Released: November 14, 2025
feature
-
[feature] [operations] Added
Operations.implementation_for.replaceparameter to
Operations.implementation_for(), allowing replacement of existing
operation implementations. This allows for existing operations such as
CreateTableOpto be extended directly. Pull request courtesy
justanothercatgirl.References: #1750
bug
-
[bug] [mssql] Fixed issue in SQL Server dialect where the DROP that's automatically
emitted for existing default constraints during an ALTER COLUMN needs to
take place before not just the modification of the column's default, but
also before the column's type is changed.References: #1744
1.17.1
1.17.1
Released: October 28, 2025
usecase
-
[usecase] [commands] Added
command.current.check_headsparameter to
command.current()command, available from the command line via the
--check-headsoption toalembic current. This tests if all head
revisions are applied to the database and raisesDatabaseNotAtHead
(or from the command line, exits with a non-zero exit code) if this is not
the case. The parameter operates equvialently to the cookbook recipe
cookbook_check_heads. Pull request courtesy Stefan Scherfke.References: #1705
bug
-
[bug] [commands] Disallow ':' character in custom revision identifiers. Previously, using a
colon in a revision ID (e.g., 'REV:1') would create the revision, however
revisions with colons in them are not correctly interpreted by other
commands, as it overlaps with the revision range syntax. Pull request
courtesy Kim Wooseok with original implementation by Hrushikesh Patil.References: #1540
1.17.0
1.17.0
Released: October 11, 2025
-
[change] [tests] The top-level test runner has been changed to use
nox, adding a
noxfile.pyas well as some included modules. Thetox.inifile
remains in place so thattoxruns will continue to function in the near
term, however it will be eventually removed and improvements and
maintenance going forward will be only towardsnoxfile.py. -
[change] [general] The minimum Python version is now 3.10, as Python 3.9 is EOL.