Skip to content

Releases: sqlalchemy/alembic

1.4.0

04 Feb 21:07
Compare
Choose a tag to compare

1.4.0

Released: February 4, 2020

feature

  • [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.

    References: #640

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.

    References: #647

  • [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.

    References: #605

usecase

  • [usecase] [environment] Moved the use of the __file__ attribute at the base of the Alembic
    package into the one place that it is specifically needed, which is when
    the config attempts to locate the template directory. This helps to allow
    Alembic to be fully importable in environments that are using Python
    memory-only import schemes. Pull request courtesy layday.

    References: #648

misc

  • [change] The internal inspection routines no longer use SQLAlchemy's
    Inspector.from_engine() method, which is expected to be deprecated in
    1.4. The inspect() function is now used.

1.3.3

22 Jan 17:02
Compare
Choose a tag to compare

1.3.3

Released: January 22, 2020

bug

  • [bug] [postgresql] Fixed issue where COMMENT directives for PostgreSQL failed to correctly
    include an explicit schema name, as well as correct quoting rules for
    schema, table, and column names. Pull request courtesy Matthew Sills.

    References: #637

usecase

  • [usecase] [operations] Added support for rendering of "computed" elements on Column
    objects, supported in SQLAlchemy via the new Computed element
    introduced in version 1.3.11. Pull request courtesy Federico Caselli.

    Note that there is currently no support for ALTER COLUMN to add, remove, or
    modify the "GENERATED ALWAYS AS" element from a column; at least for
    PostgreSQL, it does not seem to be supported by the database. Additionally,
    SQLAlchemy does not currently reliably reflect the "GENERATED ALWAYS AS"
    phrase from an existing column, so there is also no autogenerate support
    for addition or removal of the Computed element to or from an
    existing column, there is only support for adding new columns that include
    the Computed element. In the case that the Computed
    element is removed from the Column object in the table metadata,
    PostgreSQL and Oracle currently reflect the "GENERATED ALWAYS AS"
    expression as the "server default" which will produce an op that tries to
    drop the element as a default.

    References: #624

1.3.2

16 Dec 18:49
Compare
Choose a tag to compare

1.3.2

Released: December 16, 2019

bug

  • [bug] [api] [autogenerate] Fixed regression introduced by #579 where server default rendering
    functions began to require a dialect implementation, however the
    render_python_code() convenience function did not include one, thus
    causing the function to fail when used in a server default context. The
    function now accepts a migration context argument and also creates one
    against the default dialect if one is not provided.

    References: #635

1.3.1

15 Nov 06:02
Compare
Choose a tag to compare

1.3.1

no release date

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.

    References: #621

1.3.0

12 Nov 02:27
Compare
Choose a tag to compare

1.3.0

Released: October 31, 2019

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.

    References: #608

bug

  • [bug] [autogenerate] Fixed bug in new Variant autogenerate where the order of the arguments to
    Variant were mistakenly reversed.

    References: #131

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

12 Nov 02:27
Compare
Choose a tag to compare

1.2.1

Released: September 24, 2019

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.

    References: #601

  • [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.

    References: #592

1.2.0

20 Sep 14:37
Compare
Choose a tag to compare

1.2.0

Released: September 20, 2019

  • [command] [feature] 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.

    References: #473

  • [autogenerate] [bug] Improved the Python rendering of a series of migration operations such that
    a single "pass" is rendered for a UpgradeOps or
    DowngradeOps based on if no lines of Python code actually
    rendered under the operation, rather than whether or not sub-directives
    exist. Removed extra "pass" lines that would generate from the
    ModifyTableOps directive so that these aren't duplicated under
    operation rewriting scenarios.

    References: #550

  • [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.

    References: #123

  • [change: py3k] Python 3.4 support is dropped, as the upstream tooling (pip, mysqlclient)
    etc are already dropping support for Python 3.4, which itself is no longer
    maintained.

  • [autogenerate] [usecase] Added autogenerate support for Column objects that have
    dialect-specific **kwargs, support first added in SQLAlchemy 1.3.
    This includes SQLite "on conflict" as well as options used by some
    third party dialects.

    References: #518

  • [autogenerate] [usecase] Added rendering for SQLAlchemy Variant datatypes, which render as the
    base type plus one or more .with_variant() method calls.

    References: #131

  • [commands] [feature] 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.

    References: #307

  • [commands] [usecase] Made the command interface revision lookup behavior more strict in that an
    Alembic revision number is only resolved based on a partial match rules if
    it has at least four characters, to prevent simple typographical issues
    from inadvertently running migrations.

    References: #534

  • [environment] [feature] 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.

    References: #463

  • [autogenerate] [bug] Fixed bug where rendering of comment text for table-level comments within
    Operations.create_table_comment() and
    Operations.drop_table_comment() was not properly quote-escaped
    within rendered Python code for autogenerate.

    References: #549

  • [autogenerate] [bug] Modified the logic of the Rewriter object such that it keeps a
    memoization of which directives it has processed, so that it can ensure it
    processes a particular directive only once, and additionally fixed
    Rewriter so that it functions correctly for multiple-pass
    autogenerate schemes, such as the one illustrated in the "multidb"
    template. By tracking which directives have been processed, a
    multiple-pass scheme which calls upon the Rewriter multiple times
    for the same structure as elements are added can work without running
    duplicate operations on the same elements more than once.

    References: #505

1.1.0

17 Sep 22:09
Compare
Choose a tag to compare

1.1.0

Released: August 26, 2019

  • [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.

  • [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.

    References: #562

  • [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.

    References: #594

  • [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.

    References: #592

  • [commands] [usecase] 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.

    References: #571

1.0.11

17 Sep 22:09
Compare
Choose a tag to compare

1.0.11

Released: June 25, 2019

  • [autogenerate] [batch] [bug] [sqlite] 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.

    References: #579

  • [autogenerate] [bug] [sqlite] 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.

    References: #579

  • [autogenerate] [bug] 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.

  • [bug] [mysql] 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.

    References: #554

  • [bug] [mysql] [operations] 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.

    References: #564

  • [bug] [environment] 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.

  • [bug] [py3k] 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.

    References: #563

1.0.10

17 Sep 22:09
Compare
Choose a tag to compare

1.0.10

Released: April 28, 2019

  • [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.

    References: #552

  • [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.

    References: #551

  • [autogenerate] [bug] [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.

    References: #553