1.4.0
[feature] [batch]
Added new parameters BatchOperations.add_column.insert_before, BatchOperations.add_column.insert_after which provide for establishing the specific position in which a new column should be placed. Also added Operations.batch_alter_table.partial_reordering which allows the complete set of columns to be reordered when the new table is created. Both operations apply only to when batch mode is recreating the whole table using recreate="always". Thanks to Marcin Szymanski for assistance with the implementation.
bug
[bug] [autogenerate]
Adjusted the unique constraint comparison logic in a similar manner as that of 421 did for indexes in order to take into account SQLAlchemy’s own truncation of long constraint names when a naming convention is in use. Without this step, a name that is truncated by SQLAlchemy based on a unique constraint naming convention or hardcoded name will not compare properly.
[bug] [autogenerate]
A major rework of the “type comparison” logic is in place which changes the entire approach by which column datatypes are compared. Types are now compared based on the DDL string generated by the metadata type vs. the datatype reflected from the database. This means we compare types based on what would actually render and additionally if elements of the types change like string length, those changes are detected as well. False positives like those generated between SQLAlchemy Boolean and MySQL TINYINT should also be resolved. Thanks very much to Paul Becotte for lots of hard work and patience on this one.
1.3.1
bug
[bug] [mssql]
Fixed bug in MSSQL dialect where the drop constraint execution steps used to remove server default or implicit foreign key constraint failed to take into account the schema name of the target table.
1.3.0
feature
[feature] [command]
Added support for ALEMBIC_CONFIG environment variable, refers to the location of the alembic configuration script in lieu of using the -c command line option.
bug
[bug] [autogenerate]
Fixed bug in new Variant autogenerate where the order of the arguments to Variant were mistakenly reversed.
misc
[change] [compatibility]
Some internal modifications have been made to how the names of indexes and unique constraints work to make use of new functions added in SQLAlchemy 1.4, so that SQLAlchemy has more flexibility over how naming conventions may be applied to these objects.
1.2.1
bug
[bug] [command]
Reverted the name change of the “revisions” argument to command.stamp() to “revision” as apparently applications are calling upon this argument as a keyword name. Pull request courtesy Thomas Bechtold. Special translations are also added to the command line interface so that it is still known as “revisions” in the CLI.
[bug] [tests]
Removed the “test requirements” from “setup.py test”, as this command now only emits a removal error in any case and these requirements are unused.
1.2.0
feature
[feature] [command]
Added new --purge flag to the alembic stamp command, which will unconditionally erase the version table before stamping anything. This is useful for development where non-existent version identifiers might be left within the table. Additionally, alembic.stamp now supports a list of revision identifiers, which are intended to allow setting up muliple heads at once. Overall handling of version identifiers within the alembic.stamp command has been improved with many new tests and use cases added.
[feature] [runtime]
Added new feature MigrationContext.autocommit_block(), a special directive which will provide for a non-transactional block inside of a migration script. The feature requres that: the database driver (e.g. DBAPI) supports the AUTOCOMMIT isolation mode. The directive also necessarily needs to COMMIT the existing transaction in progress in order to enter autocommit mode.
[feature] [commands]
Added “post write hooks” to revision generation. These allow custom logic to run after a revision Python script is generated, typically for the purpose of running code formatters such as “Black” or “autopep8”, but may be used for any arbitrary post-render hook as well, including custom Python functions or scripts. The hooks are enabled by providing a [post_write_hooks] section in the alembic.ini file. A single hook is provided which runs an arbitrary Python executable on the newly generated revision script, which can be configured to run code formatters such as Black; full examples are included in the documentation.
[feature] [environment]
Added new flag --package to alembic init. For environments where the Alembic migration files and such are within the package tree and importable as modules, this flag can be specified which will add the additional __init__.py files in the version location and the environment location.
1.1.0:
bug
[bug] [commands]
Fixed bug where the double-percent logic applied to some dialects such as psycopg2 would be rendered in --sql mode, by allowing dialect options to be passed through to the dialect used to generate SQL and then providing paramstyle="named" so that percent signs need not be doubled. For users having this issue, existing env.py scripts need to add dialect_opts={"paramstyle": "named"} to their offline context.configure(). See the alembic/templates/generic/env.py template for an example.
[bug] [py3k]
Fixed use of the deprecated “imp” module, which is used to detect pep3147 availability as well as to locate .pyc files, which started emitting deprecation warnings during the test suite. The warnings were not being emitted earlier during the test suite, the change is possibly due to changes in py.test itself but this is not clear. The check for pep3147 is set to True for any Python version 3.5 or greater now and importlib is used when available. Note that some dependencies such as distutils may still be emitting this warning. Tests are adjusted to accommodate for dependencies that emit the warning as well.
[bug] [mysql]
Fixed issue where emitting a change of column name for MySQL did not preserve the column comment, even if it were specified as existing_comment.
[bug] [setup]
Removed the “python setup.py test” feature in favor of a straight run of “tox”. Per Pypa / pytest developers, “setup.py” commands are in general headed towards deprecation in favor of tox. The tox.ini script has been updated such that running “tox” with no arguments will perform a single run of the test suite against the default installed Python interpreter.
usecase
[usecase] [commands]
The “alembic init” command will now proceed if the target directory exists as long as it’s still empty. Previously, it would not proceed if the directory existed. The new behavior is modeled from what git does, to accommodate for container or other deployments where an Alembic target directory may need to be already mounted instead of being created with alembic init. Pull request courtesy Aviskar KC.
misc
[change]
Alembic 1.1 bumps the minimum version of SQLAlchemy to 1.1. As was the case before, Python requirements remain at Python 2.7, or in the 3.x series Python 3.4.
[change] [internals]
The test suite for Alembic now makes use of SQLAlchemy’s testing framework directly. Previously, Alembic had its own version of this framework that was mostly copied from that of SQLAlchemy to enable testing with older SQLAlchemy versions. The majority of this code is now removed so that both projects can leverage improvements from a common testing framework.
version: 1.0.11
SQLite server default reflection will ensure parenthesis are surrounding a
column default expression that is detected as being a non-constant
expression, such as a datetime() default, to accommodate for the
requirement that SQL expressions have to be parenthesized when being sent
as DDL. Parenthesis are not added to constant expressions to allow for
maximum cross-compatibility with other dialects and existing test suites
(such as Alembic's), which necessarily entails scanning the expression to
eliminate for constant numeric and string values. The logic is added to the
two "reflection->DDL round trip" paths which are currently autogenerate and
batch migration. Within autogenerate, the logic is on the rendering side,
whereas in batch the logic is installed as a column reflection hook.
Improved SQLite server default comparison to accommodate for a text()
construct that added parenthesis directly vs. a construct that relied
upon the SQLAlchemy SQLite dialect to render the parenthesis, as well
as improved support for various forms of constant expressions such as
values that are quoted vs. non-quoted.
Fixed bug where the "literal_binds" flag was not being set when
autogenerate would create a server default value, meaning server default
comparisons would fail for functions that contained literal values.
Added support for MySQL "DROP CHECK", which is added as of MySQL 8.0.16,
separate from MariaDB's "DROP CONSTRAINT" for CHECK constraints. The MySQL
Alembic implementation now checks for "MariaDB" in server_version_info to
decide which one to use.
Fixed issue where MySQL databases need to use CHANGE COLUMN when altering a
server default of CURRENT_TIMESTAMP, NOW() and probably other functions
that are only usable with DATETIME/TIMESTAMP columns. While MariaDB
supports both CHANGE and ALTER COLUMN in this case, MySQL databases only
support CHANGE. So the new logic is that if the server default change is
against a DateTime-oriented column, the CHANGE format is used
unconditionally, as in the vast majority of cases the server default is to
be CURRENT_TIMESTAMP which may also be potentially bundled with an "ON
UPDATE CURRENT_TIMESTAMP" directive, which SQLAlchemy does not currently
support as a distinct field. The fix addiionally improves the server
default comparison logic when the "ON UPDATE" clause is present and
there are parenthesis to be adjusted for as is the case on some MariaDB
versions.
Warnings emitted by Alembic now include a default stack level of 2, and in
some cases it's set to 3, in order to help warnings indicate more closely
where they are originating from. Pull request courtesy Ash Berlin-Taylor.
Replaced the Python compatbility routines for getargspec() with a fully
vendored version based on getfullargspec() from Python 3.3.
Originally, Python was emitting deprecation warnings for this function in
Python 3.8 alphas. While this change was reverted, it was observed that
Python 3 implementations for getfullargspec() are an order of magnitude
slower as of the 3.4 series where it was rewritten against Signature.
While Python plans to improve upon this situation, SQLAlchemy projects for
now are using a simple replacement to avoid any future issues.
1.0.10
bug
[bug] [commands]
Fixed bug introduced in release 0.9.0 where the helptext for commands inadvertently got expanded to include function docstrings from the command.py module. The logic has been adjusted to only refer to the first line(s) preceding the first line break within each docstring, as was the original intent.
[bug] [mysql] [operations]
Added an assertion in RevisionMap.get_revisions() and other methods which ensures revision numbers are passed as strings or collections of strings. Driver issues particularly on MySQL may inadvertently be passing bytes here which leads to failures later on.
[bug] [autogenerate] [mysql]
Fixed bug when using the EnvironmentContext.configure.compare_server_default flag set to True where a server default that is introduced in the table metadata on an Integer column, where there is no existing server default in the database, would raise a TypeError.
1.0.9
bug
[bug] [operations]
Simplified the internal scheme used to generate the alembic.op namespace to no longer attempt to generate full method signatures (e.g. rather than generic *args, **kw) as this was not working in most cases anyway, while in rare circumstances it would in fact sporadically have access to the real argument names and then fail when generating the function due to missing symbols in the argument signature.
1.0.8
bug
[bug] [operations] Removed use of deprecated force parameter for SQLAlchemy quoting functions as this parameter will be removed in a future release. Pull request courtesy Parth Shandilya(ParthS007).
[bug] [autogenerate] [postgresql] [py3k] Fixed issue where server default comparison on the PostgreSQL dialect would fail for a blank string on Python 3.7 only, due to a change in regular expression behavior in Python 3.7.
1.0.7
[bug] [autogenerate] Fixed issue in new comment support where autogenerated Python code for comments wasn’t using repr() thus causing issues with quoting
1.0.6
feature
[feature] [operations] Added Table and Column level comments for supported backends. New methods Operations.create_table_comment() and Operations.drop_table_comment() are added. A new arguments Operations.alter_column.comment and Operations.alter_column.existing_comment are added to Operations.alter_column(). Autogenerate support is also added to ensure comment add/drops from tables and columns are generated as well as that Operations.create_table(), Operations.add_column() both include the comment field from the source Table or Column object.
1.0.5
* Resolved remaining Python 3 deprecation warnings, covering the use of inspect.formatargspec() with a vendored version copied from the Python standard library, importing collections.abc above Python 3.3 when testing against abstract base classes, fixed one occurrence of log.warn(), as well as a few invalid escape sequences.
1.0.4
* Code hosting has been moved to GitHub, at https://github.com/sqlalchemy/alembic. Additionally, the main Alembic website documentation URL is now https://alembic.sqlalchemy.org.
1.0.3:
Fixed regression caused by 513, where the logic to consume mssql_include was not correctly interpreting the case where the flag was not present, breaking the op.create_index directive for SQL Server as a whole
1.0.2:
[bug] [autogenerate] The system=True flag on Column, used primarily in conjunction with the Postgresql “xmin” column, now renders within the autogenerate render process, allowing the column to be excluded from DDL. Additionally, adding a system=True column to a model will produce no autogenerate diff as this column is implicitly present in the database.
[bug] [mssql] Fixed issue where usage of the SQL Server mssql_include option within a Operations.create_index() would raise a KeyError, as the additional column(s) need to be added to the table object used by the construct internally.
1.0.1:
Fixed an issue where revision descriptions were essentially being formatted twice. Any revision description that contained characters like %, writing output to stdout will fail because the call to config.print_stdout attempted to format any additional args passed to the function. This fix now only applies string formatting if any args are provided along with the output text.
Fixed issue where removed method union_update() was used when a customized MigrationScript instance included entries in the .imports data member, raising an AttributeError.
1.0.0:
[feature] [general] For Alembic 1.0, Python 2.6 / 3.3 support is being dropped, allowing a fixed setup.py to be built as well as universal wheels. Pull request courtesy Hugo.
[feature] [general] With the 1.0 release, Alembic’s minimum SQLAlchemy support version moves to 0.9.0, previously 0.7.9.
[bug] [batch] Fixed issue in batch where dropping a primary key column, then adding it back under the same name but without the primary_key flag, would not remove it from the existing PrimaryKeyConstraint. If a new PrimaryKeyConstraint is added, it is used as-is, as was the case before.
version 0.9.10
The "op.drop_constraint()" directive will now render using repr() for
the schema name, in the same way that "schema" renders for all the other op
directives.
Added basic capabilities for external dialects to support rendering of
"nested" types, like arrays, in a manner similar to that of the Postgresql
dialect.
Fixed issue where "autoincrement=True" would not render for a column that
specified it, since as of SQLAlchemy 1.1 this is no longer the default
value for "autoincrement". Note the behavior only takes effect against the
SQLAlchemy 1.1.0 and higher; for pre-1.1 SQLAlchemy, "autoincrement=True"
does not render as was the case before.
0.9.9:
feature
Added new flag --indicate-current to the alembic history command. When listing versions, it will include the token “(current)” to indicate the given version is a current head in the target database.
bug
The fix for 455 in version 0.9.6 involving MySQL server default comparison was entirely non functional, as the test itself was also broken and didn’t reveal that it wasn’t working. The regular expression to compare server default values like CURRENT_TIMESTAMP to current_timestamp() is repaired.
Fixed bug where MySQL server default comparisons were basically not working at all due to incorrect regexp added in 455. Also accommodates for MariaDB 10.2 quoting differences in reporting integer based server defaults.
Fixed bug in op.drop_constraint() for MySQL where quoting rules would not be applied to the constraint name.
version: 0.9.8
Fixed bug where the :meth:.Script.as_revision_number method
did not accommodate for the 'heads' identifier, which in turn
caused the :meth:.EnvironmentContext.get_head_revisions
and :meth:.EnvironmentContext.get_revision_argument methods
to be not usable when multiple heads were present.
The :meth:.EnvironmentContext.get_head_revisions method returns
a tuple in all cases as documented.
Fixed bug where autogenerate of :class:.ExcludeConstraint
would render a raw quoted name for a Column that has case-sensitive
characters, which when invoked as an inline member of the Table
would produce a stack trace that the quoted name is not found.
An incoming Column object is now rendered as sa.column('name').
Fixed bug where the indexes would not be included in a
migration that was dropping the owning table. The fix
now will also emit DROP INDEX for the indexes ahead of time,
but more importantly will include CREATE INDEX in the
downgrade migration.
Fixed the autogenerate of the module prefix
when rendering the text_type parameter of
postgresql.HSTORE, in much the same way that
we do for ARRAY's type and JSON's text_type.
Added support for DROP CONSTRAINT to the MySQL Alembic
dialect to support MariaDB 10.2 which now has real
CHECK constraints. Note this change does **not**
add autogenerate support, only support for op.drop_constraint()
to work.
0.9.7
[bug] [autogenerate] Fixed regression caused by 421 which would cause case-sensitive quoting rules to interfere with the comparison logic for index names, thus causing indexes to show as added for indexes that have case-sensitive names. Works with SQLAlchemy 0.9 and later series.
[bug] [autogenerate] [postgresql] Fixed bug where autogenerate would produce a DROP statement for the index implicitly created by a Postgresql EXCLUDE constraint, rather than skipping it as is the case for indexes implicitly generated by unique constraints. Makes use of SQLAlchemy 1.0.x’s improved “duplicates index” metadata and requires at least SQLAlchemy version 1.0.x to function correctly.
0.9.6
feature
[feature] [commands] The alembic history command will now make use of the revision environment env.py unconditionally if the revision_environment configuration flag is set to True. Previously, the environment would only be invoked if the history specification were against a database-stored revision token.
bug
[bug] [commands] Fixed a few Python3.6 deprecation warnings by replacing StopIteration with return, as well as using getfullargspec() instead of getargspec() under Python 3.
[bug] [commands] An addition to 441 fixed in 0.9.5, we forgot to also filter for the + sign in migration names which also breaks due to the relative migrations feature.
[bug] [autogenerate] Fixed bug expanding upon the fix for 85 which adds the correct module import to the “inner” type for an ARRAY type, the fix now accommodates for the generic sqlalchemy.types.ARRAY type added in SQLAlchemy 1.1, rendering the inner type correctly regardless of whether or not the Postgresql dialect is present.
[bug] [mysql] Fixed bug where server default comparison of CURRENT_TIMESTAMP would fail on MariaDB 10.2 due to a change in how the function is represented by the database during reflection.
[bug] [autogenerate] Fixed bug where comparison of Numeric types would produce a difference if the Python-side Numeric inadvertently specified a non-None “scale” with a “precision” of None, even though this Numeric type will pass over the “scale” argument when rendering. Pull request courtesy Ivan Mmelnychuk.
[bug] [batch] The name of the temporary table in batch mode is now generated off of the original table name itself, to avoid conflicts for the unusual case of multiple batch operations running against the same database schema at the same time.
[bug] [autogenerate] A ForeignKeyConstraint can now render correctly if the link_to_name flag is set, as it will not attempt to resolve the name from a “key” in this case. Additionally, the constraint will render as-is even if the remote column name isn’t present on the referenced remote table.
[bug] [runtime] [py3k] Reworked “sourceless” system to be fully capable of handling any combination of: Python2/3x, pep3149 or not, PYTHONOPTIMIZE or not, for locating and loading both env.py files as well as versioning files. This includes: locating files inside of __pycache__ as well as listing out version files that might be only in versions/__pycache__, deduplicating version files that may be in versions/__pycache__ and versions/ at the same time, correctly looking for .pyc or .pyo files based on if pep488 is present or not. The latest Python3x deprecation warnings involving importlib are also corrected.
Alembic is a database migrations tool written by the author of
SQLAlchemy. A migrations tool can emit ALTER statements to a database
in order to change the structure of tables and other constructs,
provides a system whereby "migration scripts" may be constructed; each
script indicates a particular series of steps that can "upgrade" a
target database to a new version, and optionally a series of steps
that can "downgrade" similarly, doing the same steps in reverse, and
allows the scripts to execute in some sequential manner.
Packaged by Kamel Ibn Aziz Derouiche and updated by me.