A database migrations tool for SQLAlchemy.

Overview

Alembic is a database migrations tool written by the author of SQLAlchemy. A migrations tool offers the following functionality:

  • 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.
  • Allows the scripts to execute in some sequential manner.

The goals of Alembic are:

  • Very open ended and transparent configuration and operation. A new Alembic environment is generated from a set of templates which is selected among a set of options when setup first occurs. The templates then deposit a series of scripts that define fully how database connectivity is established and how migration scripts are invoked; the migration scripts themselves are generated from a template within that series of scripts. The scripts can then be further customized to define exactly how databases will be interacted with and what structure new migration files should take.
  • Full support for transactional DDL. The default scripts ensure that all migrations occur within a transaction - for those databases which support this (Postgresql, Microsoft SQL Server), migrations can be tested with no need to manually undo changes upon failure.
  • Minimalist script construction. Basic operations like renaming tables/columns, adding/removing columns, changing column attributes can be performed through one line commands like alter_column(), rename_table(), add_constraint(). There is no need to recreate full SQLAlchemy Table structures for simple operations like these - the functions themselves generate minimalist schema structures behind the scenes to achieve the given DDL sequence.
  • "auto generation" of migrations. While real world migrations are far more complex than what can be automatically determined, Alembic can still eliminate the initial grunt work in generating new migration directives from an altered schema. The --autogenerate feature will inspect the current status of a database using SQLAlchemy's schema inspection capabilities, compare it to the current state of the database model as specified in Python, and generate a series of "candidate" migrations, rendering them into a new migration script as Python directives. The developer then edits the new file, adding additional directives and data migrations as needed, to produce a finished migration. Table and column level changes can be detected, with constraints and indexes to follow as well.
  • Full support for migrations generated as SQL scripts. Those of us who work in corporate environments know that direct access to DDL commands on a production database is a rare privilege, and DBAs want textual SQL scripts. Alembic's usage model and commands are oriented towards being able to run a series of migrations into a textual output file as easily as it runs them directly to a database. Care must be taken in this mode to not invoke other operations that rely upon in-memory SELECTs of rows - Alembic tries to provide helper constructs like bulk_insert() to help with data-oriented operations that are compatible with script-based DDL.
  • Non-linear, dependency-graph versioning. Scripts are given UUID identifiers similarly to a DVCS, and the linkage of one script to the next is achieved via human-editable markers within the scripts themselves. The structure of a set of migration files is considered as a directed-acyclic graph, meaning any migration file can be dependent on any other arbitrary set of migration files, or none at all. Through this open-ended system, migration files can be organized into branches, multiple roots, and mergepoints, without restriction. Commands are provided to produce new branches, roots, and merges of branches automatically.
  • Provide a library of ALTER constructs that can be used by any SQLAlchemy application. The DDL constructs build upon SQLAlchemy's own DDLElement base and can be used standalone by any application or script.
  • At long last, bring SQLite and its inablity to ALTER things into the fold, but in such a way that SQLite's very special workflow needs are accommodated in an explicit way that makes the most of a bad situation, through the concept of a "batch" migration, where multiple changes to a table can be batched together to form a series of instructions for a single, subsequent "move-and-copy" workflow. You can even use "move-and-copy" workflow for other databases, if you want to recreate a table in the background on a busy system.

Documentation and status of Alembic is at https://alembic.sqlalchemy.org/

The SQLAlchemy Project

Alembic is part of the SQLAlchemy Project and adheres to the same standards and conventions as the core project.

Development / Bug reporting / Pull requests

Please refer to the SQLAlchemy Community Guide for guidelines on coding and participating in this project.

Code of Conduct

Above all, SQLAlchemy places great emphasis on polite, thoughtful, and constructive communication between users and developers. Please see our current Code of Conduct at Code of Conduct.

License

Alembic is distributed under the MIT license.

Comments
  • Update the type comparison code used for schema autogeneration. Compare

    Update the type comparison code used for schema autogeneration. Compare

    the output text for the type to look for changes. In addition, allow schemas to define sets of types that are functionally equivalent, such as BOOL and TINYINT(1). #605

    opened by pbecotte 38
  • Multiple versions directories

    Multiple versions directories

    Migrated issue, originally created by Wichert Akkerman (@wichert)

    I have a collection of packages, each of which import one or more models that may be used in an application. Each package can require its own migrations, but will may depend on migrations from other packages it depends on as well. I am looking at what it would take to use alembic in this type of environment. I see two basic approaches: manually importing versions, or allowing versions in multiple places.

    Manual importing of versions

    One option is to turn the versions directory into a package and import the downgrade and upgrade functions defined there in a version definition of another package. This does not require any changes in alembic

    from other.package.versions.v3_0 import downgrade as downgrade_other
    from other.package.versions.v3_0 import upgrade as upgrade_other
    
    def upgrade():
        upgrade_other()
        # Upgrade logic for this package
    
    def downgrade():
        downgrade_other()
        # Downgrade logic for this package
    

    This works, but quickly becomes problematic as soon as the dependencies are not completely trivial.

    Versions in multiple places

    Alembic has an undocumented option allowing you use a dotted path as version location. It should be easy to extend this to allow multiple version directories.

    [alembic]
    script_location =
        other.package:upgrade
        other.package2:upgrade
        my_package:upgrade
    

    You can then treat each package as a branch to make sure all migration dependencies are handled correctly.

    If you think this approach is workable I can probably whip up a pull request for it.

    feature versioning model 
    opened by sqlalchemy-bot 37
  • Autogenerate detected removed index, for constraints

    Autogenerate detected removed index, for constraints

    Migrated issue, originally created by John Kida (@jkida)

    (Postgresql) It appears everywhere I have a constraint in my sqlalchemy code in which there is a unique constaint index alembic --autogenerate wants to remove it.

    ie. python code: lead_id = Column(Integer, ForeignKey('crm_lead.id'), unique=True)

    DataBase \d: Indexes: "chat_pkey" PRIMARY KEY, btree (id) "chat_lead_id_key" UNIQUE CONSTRAINT, btree (lead_id)

    INFO [alembic.autogenerate.compare] Detected removed index 'chat_lead_id_key' on 'chat'

    It appears alembic does not consider constraints as indexes, and psql does.

    bug autogenerate - detection 
    opened by sqlalchemy-bot 34
  • [Question]Can i use async db driver to serve db changes?

    [Question]Can i use async db driver to serve db changes?

    Hi guys! I'm newbie with alembic and wanted clarify one thing.

    As i understood based on docs, alembic uses sync database driver(for example, psycopg2) to serve db changes. At the same time i saw SQLAlchemy is moving forward with async, which means i can use asyncpg. As result, it seems app need has both of them - psycopg2 and asyncpg.

    Is it possible to use just asyncpg for alembic and SQLAlchemy? Or maybe it's planned future feature? I know that alembic don't need async features to modify db, but i think it's good for "clean requirements" purpose use one driver for both cases. Or i'm wrong and maybe missing something?

    Thanks!

    migration environment documentation use case asyncio 
    opened by crotaoryx 33
  • Column renames not supported on SQLite

    Column renames not supported on SQLite

    Migrated issue, originally created by Wichert Akkerman (@wichert)

    SQLite does not support renaming a column directly, so you need a magic dance: create a new column, copy the right data to it and then remove the old column, taking care to only add constraints after copying the data.

    feature op directives batch migrations 
    opened by sqlalchemy-bot 31
  • Broken pipe when using `head` to display only the first lines of history

    Broken pipe when using `head` to display only the first lines of history

    Migrated issue, originally created by Janne Vanhala (@jpvanhal)

    I have hundreds of migrations in a project. I would like to list only the most recent ones. If I use head like this:

    alembic history | head
    

    Only the first 10 lines of alembic history are correctly printed, but then Alembic crashes with the following exception:

    Traceback (most recent call last):
      File "/Users/janne/.virtualenvs/project/bin/alembic", line 9, in <module>
        load_entry_point('alembic==0.6.1', 'console_scripts', 'alembic')()
      File "/Users/janne/.virtualenvs/project/lib/python2.7/site-packages/alembic/config.py", line 298, in main
        CommandLine(prog=prog).main(argv=argv)
      File "/Users/janne/.virtualenvs/project/lib/python2.7/site-packages/alembic/config.py", line 293, in main
        self.run_cmd(cfg, options)
      File "/Users/janne/.virtualenvs/project/lib/python2.7/site-packages/alembic/config.py", line 279, in run_cmd
        **dict((k, getattr(options, k)) for k in kwarg)
      File "/Users/janne/.virtualenvs/project/lib/python2.7/site-packages/alembic/command.py", line 193, in history
        _display_history(config, script, base, head)
      File "/Users/janne/.virtualenvs/project/lib/python2.7/site-packages/alembic/command.py", line 171, in _display_history
        config.print_stdout(sc.log_entry)
      File "/Users/janne/.virtualenvs/project/lib/python2.7/site-packages/alembic/config.py", line 95, in print_stdout
        "\n"
      File "/Users/janne/.virtualenvs/project/lib/python2.7/site-packages/alembic/util.py", line 139, in write_outstream
        stream.write(t)
    IOError: [Errno 32] Broken pipe
    
    bug command interface 
    opened by sqlalchemy-bot 29
  • Reduce dependencies for running migration

    Reduce dependencies for running migration

    Hi,

    Alembic requires Mako and python-editor. I suspect that alembic requires theses libraries only for alembic revision command. This command is useful only for developer.

    When using alembic to apply migration on production, we don't need to create new revisions. Thus, theses dependencies are useless on production.

    Would it be possible to have a subset of alembic feature for production deployement including only upgradate, downgrade and other introspection command without init, revision and other development commands ?

    Regards,

    feature 
    opened by bersace 28
  • add environment control for *all* ScriptDirectory commands

    add environment control for *all* ScriptDirectory commands

    Migrated issue, originally created by Mischa (@mischas)

    continuing from #447:

    all commands that use ScriptDirectory.from_config() should be altered to use a context manager that examines "revision_environment" and then optionally makes use of EnvironmentContext.

    the idea is that people are now coding imports into their revision files that need to be pulled in from env.py in order for the files to be importable. ScriptDirectory is not usable without this directive.

    bug command interface Fast-Track 
    opened by sqlalchemy-bot 28
  • v1.4.2 missing wheel when pip download and then pip install from .tar.gz

    v1.4.2 missing wheel when pip download and then pip install from .tar.gz

    When I pip download alembic==1.4.2 and then pip install alembic from the downloaded .tar.gz file, then I get the following error:

      ERROR: Command errored out with exit status 1:                                                                                                                                                            
       command: /home/myself/anaconda3/envs/tmp3/bin/python /home/myself/anaconda3/envs/tmp3/lib/python3.7/site-packages/pip install --ignore-installed --no-user --prefix /tmp/pip-build-env-c_bv0n7g/overlay
     --no-warn-script-location --no-binary :none: --only-binary :none: --no-index --find-links /home/myself/workspace/my_project/./ -- 'setuptools>=40.8.0' wheel                                          
           cwd: None                                                                                                                                                                                            
      Complete output (4 lines):                                                                                                                                                                                
      Looking in links: /home/myself/workspace/my_project/./                                                                                                                                               
      Processing ./setuptools-46.0.0-py3-none-any.whl                                                                                                                                                           
      ERROR: Could not find a version that satisfies the requirement wheel (from versions: none)                                                                                                                
      ERROR: No matching distribution found for wheel                                                                                                                                                           
      ----------------------------------------                                                                                                                                                                  
    ERROR: Command errored out with exit status 1: /home/myself/anaconda3/envs/tmp3/bin/python /home/myself/anaconda3/envs/tmp3/lib/python3.7/site-packages/pip install --ignore-installed --no-user --prefix
    /tmp/pip-build-env-c_bv0n7g/overlay --no-warn-script-location --no-binary :none: --only-binary :none: --no-index --find-links /home/myself/workspace/my_project/./ -- 'setuptools>=40.8.0' wheel Check
    the logs for full command output.
    
    

    However, the same procedure works with the versions before, like 1.4.1.

    bug installation 
    opened by LGro 25
  • Subtle problems related to branch–rebase migrations

    Subtle problems related to branch–rebase migrations

    Migrated issue, originally created by Hong Minhee (@dahlia)

    It’s hard to explain well for me, so I will show you some figures.

    Let’s suppose we have one deployed directory (production) and two local directories for development (dev-local-a, dev-local-b):

    [production]   [dev-local-a]   [dev-local-b]
    * A            * A             * A
    

    And then each developer works on their local directory. Migrations B and C are added to different directories. Note that (+) indicates it’s not executed (upgraded) yet:

    [production]   [dev-local-a]   [dev-local-b]
    * A            * A             * A
                   |               |
                   * B (+)         * C (+)
    

    They execute migrations that they have just added:

    [production]   [dev-local-a]   [dev-local-b]
    * A            * A             * A
                   |               |
                   * B             * C
    

    And then developer A (dev-local-a) deploys changes he made and migration B is also immediately executed in the production. At the same time, developer B (dev-local-b) pulls changes from upstream, so a branch is made (C and B):

    [production]   [dev-local-a]   [dev-local-b]
    * A            * A             * A
    |              |               |\
    * B            * B             | * C
                                   |
                                   * B (+)
    

    In this situation developer B has two options to go. First option is to place B (which is not executed in his database yet) in front of C he made:

    [production]   [dev-local-a]   [dev-local-b]
    * A            * A             * A
    |              |               |
    * B            * B             * B (+)
                                   |
                                   * C
    

    Since B is not executed, some features depending on it are broken. He might be not even aware of that. If he fortunately becomes aware of that, he should downgrade his database to A first to execute B. Data that depend on C are also lost during this process. [Problem A]

    Second option, probably more natural for developer B, is to place B (which is not executed yet) in back of C he made:

    [production]   [dev-local-a]   [dev-local-b]
    * A            * A             * A
    |              |               |
    * B            * B             * C
                                   |
                                   * B (+)
    

    He can easily upgrade his database to B, but the problem happens when he deploys changes he made:

    [production]   [dev-local-a]   [dev-local-b]
    * A            * A             * A
    |              |               |
    * C (+)        * B             * C
    |                              |
    * B                            * B
    

    C is left as still not executed, because the database is already marked upgrade to B. [Problem B] I think this problem is more significant than problem A I show you above.

    Although there could be several ways to resolve these problems, I’d like to suggest a way: how about introducing merge migration that has two parents as like Git or Mercurial do?

    Thanks!

    duplicate feature versioning model 
    opened by sqlalchemy-bot 25
  • Make version table name configurable

    Make version table name configurable

    Migrated issue, originally created by Karol Kuczmarski (@Xion)

    It's currently alembic_version, but it would be nice if this was configurable - either in alembic.ini, or (more likely) in env.py.

    feature 
    opened by sqlalchemy-bot 24
  • add overload stubs for proxied classes

    add overload stubs for proxied classes

    Description

    Closes #1146 Closes #1147

    Overloaded functions would not have type stubs generated by the stub generator for proxied classes. Now they will.

    Checklist

    This pull request is:

    • [ ] A documentation / typographical error fix
      • Good to go, no issue or tests are needed
    • [x] A short code fix
      • please include the issue number, and create an issue if none exists, which must include a complete example of the issue. one line code fixes without an issue and demonstration will not be accepted.
      • Please include: Fixes: #<issue number> in the commit message
      • please include tests. one line code fixes without tests will not be accepted.
    • [ ] A new feature implementation
      • please include the issue number, and create an issue if none exists, which must include a complete example of how the feature would look.
      • Please include: Fixes: #<issue number> in the commit message
      • please include tests.
    opened by vfazio 6
  • overload stubs missing for get_x_argument

    overload stubs missing for get_x_argument

    Describe the bug

    The context.pyi does not have stubs for the function overloads specified in environment.py

        @overload
        def get_x_argument(  # type:ignore[misc]
            self, as_dictionary: Literal[False] = ...
        ) -> List[str]:
            ...
    
        @overload
        def get_x_argument(  # type:ignore[misc]
            self, as_dictionary: Literal[True] = ...
        ) -> Dict[str, str]:
            ...
    
        def get_x_argument(
            self, as_dictionary: bool = False
        ) -> Union[List[str], Dict[str, str]]:
    

    This will cause typing errors if trying to use:

    cmd_line_path = context.get_x_argument(as_dictionary=True).get("dbpath", None)
    
    migrations/env.py:71:21: error: Item "List[str]" of "Union[List[str], Dict[str, str]]" has no attribute "get"  [union-attr]
    

    Since the default typing for the function allows it to return List[str] even though specifying as_dictionary should narrow the return type.

    Expected behavior

    There should be no typing error once @overload stubs are added

    To Reproduce Please try to provide a Minimal, Complete, and Verifiable example, with the migration script and/or the SQLAlchemy tables or models involved. See also Reporting Bugs on the website.

    # Insert code here
    

    Error

    # Copy error here. Please include the full stack trace.
    

    Versions.

    • OS:
    • Python:
    • Alembic:
    • SQLAlchemy:
    • Database:
    • DBAPI:

    Additional context

    Have a nice day!

    bug pep 484 
    opened by vfazio 1
  • modify ops to have kw only set up (e.g. add the '*')

    modify ops to have kw only set up (e.g. add the '*')

    we likely have to modify tools/write_pyi to handle this, autogenerate is likely OK and the change here is probably warranting of a bigger release bump. But we should guard against issues like #1127 and we should have done this when we released for Python 3.

    bug op directives py3k 
    opened by zzzeek 2
  • Consider Removing New Line Characters when Comparing Computed Constructs

    Consider Removing New Line Characters when Comparing Computed Constructs

    I'm working with a Computed Column construct, which is really long and therefore contains line breaks for readability.

    When this construct gets imported into the underlying database (Postgres in my case), the construct gets reformatted with line breaks inserted in different places.

    This creates a small side-effect, where alembic now thinks that the original computed clause provided by the migration file is different to the one in the database, and therefore emits a warning.

    /usr/local/lib/python3.10/site-packages/alembic/autogenerate/compare.py:1090: 
    UserWarning: Computed default on ***  cannot be modified
    util.warn("Computed default on %s.%s cannot be modified" % (tname, cname))
    

    After inspecting the code, I found this method, which appears to sanitize the database computed clause as well as the local one:

    https://github.com/sqlalchemy/alembic/blob/fc451e60731ad5b8d73255f0a1996e1d4e0f20de/alembic/autogenerate/compare.py#L1047-L1055

    I feel that we should include line breaks in the list of tokens that should be removed before a comparison takes place, but happy to hear what thoughts you have on this.

    Thanks!

    bug autogenerate - detection motivated volunteers requested 
    opened by james-menzies 2
  • Augmented (TypeDecorator) JSON type results in data loss during SQLite migration

    Augmented (TypeDecorator) JSON type results in data loss during SQLite migration

    Describe the bug A sqlalchemy type created using sa.TypeDecorator with a sa.JSON impl exhibits the same SQLite-related data loss as described in #697.

    Expected behavior A type whose impl is sa.JSON should 'look' to Alembic like sa.JSON for the purposes of deciding whether to CAST the data in the column under SQLite.

    To Reproduce

    class CustomJson(sa.TypeDecorator):
        impl = sa.JSON
    
    def upgrade():
        with op.batch_alter_table('bar') as bop:
           bop.alter_column('foo', type_=CustomJson)
    

    This will result in your valid-as-JSON VARCHAR column being turned into a numeric data type with the value 0, because the SQL emitted contains the CAST clauses that need to be avoided to prevent this truncation, e.g. INSERT INTO _alembic_tmp_bar ... CAST(bar.foo AS JSON) AS foo) ...

    Versions.

    • OS: all
    • Python: all
    • Alembic: 1.8.1 and below
    • SQLAlchemy: 1.4
    • Database: SQLite
    • DBAPI: all

    Additional context

    The issue is that the original fix uses isinstance(col, sa.JSON), but a custom column type should not be an instance of a base type according to https://docs.sqlalchemy.org/en/14/core/custom_types.html#augmenting-existing-types - instead, it's an instance of sa.TypeDecorator.

    I suspect this should really be a more general purpose fix, where "sqlalchemy types hierarchy testing" in alembic should go through some kind of centralized function that understands how to 'unwrap' a sa.TypeDecorator and make its decision based on the underlying implementation.

    I'd be happy to contribute some code if the maintainers are up for accepting a PR for this issue.

    Workaround

    (for anyone else running into this and wondering what to do if it isn't fixed yet)

    Find a way to specify your columns as sa.JSON rather than your custom column in the migration. SQLite doesn't actually care (very much) what type your column is anyway. This will be ugly, but it will preserve your data, and then you can likely use the more correct column type at runtime with sqlalchemy just fine, since it seems to only be the CAST statement that causes this issue - the rest of the JSON logic lives in your sqlalchemy code.

    bug batch migrations motivated volunteers requested 
    opened by petergaultney 1
  • Fix type annotation in `op.create_table_comment`

    Fix type annotation in `op.create_table_comment`

    Description

    The existing_comment parameter had type None, but it should be Optional[str].

    Fixes #903

    Checklist

    This pull request is:

    • [x] A documentation / typographical error fix
      • Good to go, no issue or tests are needed
    • [ ] A short code fix
      • please include the issue number, and create an issue if none exists, which must include a complete example of the issue. one line code fixes without an issue and demonstration will not be accepted.
      • Please include: Fixes: #<issue number> in the commit message
      • please include tests. one line code fixes without tests will not be accepted.
    • [ ] A new feature implementation
      • please include the issue number, and create an issue if none exists, which must include a complete example of how the feature would look.
      • Please include: Fixes: #<issue number> in the commit message
      • please include tests.

    Have a nice day!

    opened by colincadams 3
Releases(rel_1_9_1)
  • rel_1_9_1(Dec 23, 2022)

    1.9.1

    Released: December 23, 2022

    bug

    • [bug] [autogenerate] Fixed issue where server default compare would not work for string defaults that contained backslashes, due to mis-rendering of these values when comparing their contents.

      References: #1145

    • [bug] [oracle] Implemented basic server default comparison for the Oracle backend; previously, Oracle's formatting of reflected defaults prevented any matches from occurring.

    • [bug] [sqlite] Adjusted SQLite's compare server default implementation to better handle defaults with or without parens around them, from both the reflected and the local metadata side.

    • [bug] [mssql] Adjusted SQL Server's compare server default implementation to better handle defaults with or without parens around them, from both the reflected and the local metadata side.

    Source code(tar.gz)
    Source code(zip)
  • rel_1_9_0(Dec 15, 2022)

    1.9.0

    Released: December 15, 2022

    feature

    • [feature] [commands] Added new Alembic command alembic check. This performs the widely requested feature of running an "autogenerate" comparison between the current database and the MetaData that's currently set up for autogenerate, returning an error code if the two do not match, based on current autogenerate settings. Pull request courtesy Nathan Louie.

      References: #724

    bug

    • [bug] [tests] Fixed issue in tox.ini file where changes in the tox 4.0 series to the format of "passenv" caused tox to not function correctly, in particular raising an error as of tox 4.0.6.

    • [bug] [typing] Fixed typing issue where revision.process_revision_directives was not fully typed; additionally ensured all Callable and Dict arguments to EnvironmentContext.configure() include parameters in the typing declaration.

      Additionally updated the codebase for Mypy 0.990 compliance.

      References: #1110

    Source code(tar.gz)
    Source code(zip)
  • rel_1_8_1(Jul 13, 2022)

    1.8.1

    Released: July 13, 2022

    bug

    • [bug] [sqlite] Fixed bug where the SQLite implementation of Operations.rename_table() would render an explicit schema name for both the old and new table name, which while is the standard ALTER syntax, is not accepted by SQLite's syntax which doesn't support a rename across schemas. In particular, the syntax issue would prevent batch mode from working for SQLite databases that made use of attached databases (which are treated as "schemas" in SQLAlchemy).

      References: #1065

    • [bug] [batch] Added an error raise for the condition where Operations.batch_alter_table() is used in --sql mode, where the operation requires table reflection, as is the case when running against SQLite without giving it a fixed Table object. Previously the operation would fail with an internal error. To get a "move and copy" batch operation as a SQL script without connecting to a database, a Table object should be passed to the Operations.batch_alter_table.copy_from parameter so that reflection may be skipped.

      References: #1021

    Source code(tar.gz)
    Source code(zip)
  • rel_1_8_0(May 31, 2022)

    1.8.0

    Released: May 31, 2022

    changed

    • [changed] [installation] Alembic 1.8 now supports Python 3.7 and above.

      References: #1025

    • [changed] [environment] The "Pylons" environment template has been removed as of Alembic 1.8. This template was based on the very old pre-Pyramid Pylons web framework which has been long superseded by Pyramid.

      References: #987

    feature

    • [feature] [typing] PEP 484 typing annotations have been added to the env.py and revision template files within migration templates. Pull request by Nikita Sobolev.

      References: #764

    usecase

    • [usecase] [operations] The op.drop_table() operation directive will now trigger the before_drop() and after_drop() DDL event hooks at the table level, which is similar to how the before_create() and after_create() hooks are triggered by the op.create_table() directive. Note that as op.drop_table() accepts only a table name and optional schema name, the Table object received by the event will not have any information within it other than the table name and schema name.

      References: #1037

    • [usecase] [commands] Added new token epoch to the file_template option, which will populate the integer epoch as determined by int(create_date.timestamp()). Pull request courtesy Caio Carvalho.

      References: #1027

    bug

    • [bug] [revisioning] Fixed issue where a downgrade using a relative revision would fail in case of multiple branches with a single effectively head due to interdependencies between revisions.

      References: #1026

    • [bug] [batch] Fixed issue in batch mode where CREATE INDEX would not use a new column name in the case of a column rename.

      References: #1034

    Source code(tar.gz)
    Source code(zip)
  • rel_1_7_7(Mar 14, 2022)

    1.7.7

    Released: March 14, 2022

    bug

    • [bug] [operations] Fixed issue where using Operations.create_table() in conjunction with a CheckConstraint that referred to table-bound Column objects rather than string expressions would be added to the parent table potentially multiple times, resulting in an incorrect DDL sequence. Pull request courtesy Nicolas CANIART.

      References: #1004

    • [bug] [environment] The logging.fileConfig() line in env.py templates, which is used to setup Python logging for the migration run, is now conditional on Config.config_file_name not being None. Otherwise, the line is skipped as there is no default logging configuration present.

      References: #986

    • [bug] [mssql] Fixed bug where an Operations.alter_column() operation would change a "NOT NULL" column to "NULL" by emitting an ALTER COLUMN statement that did not specify "NOT NULL". (In the absence of "NOT NULL" T-SQL was implicitly assuming "NULL"). An Operations.alter_column() operation that specifies Operations.alter_column.type should also specify include either Operations.alter_column.nullable or Operations.alter_column.existing_nullable to inform Alembic as to whether the emitted DDL should include "NULL" or "NOT NULL"; a warning is now emitted if this is missing under this scenario.

      References: #977

    Source code(tar.gz)
    Source code(zip)
  • rel_1_7_6(Feb 1, 2022)

    1.7.6

    Released: February 1, 2022

    usecase

    • [usecase] [commands] Add a new command alembic ensure_version, which will ensure that the Alembic version table is present in the target database, but does not alter its contents. Pull request courtesy Kai Mueller.

      References: #964

    bug

    • [bug] [batch] [regression] Fixed regression where usage of a with_variant() datatype in conjunction with the existing_type option of op.alter_column() under batch mode would lead to an internal exception.

      References: #982

    • [bug] [autogenerate] Implemented support for recognizing and rendering SQLAlchemy "variant" types going forward into SQLAlchemy 2.0, where the architecture of "variant" datatypes will be changing.

    • [bug] [autogenerate] [mysql] Added a rule to the MySQL impl so that the translation between JSON / LONGTEXT is accommodated by autogenerate, treating LONGTEXT from the server as equivalent to an existing JSON in the model.

      References: #968

    misc

    • [mssql] Removed a warning raised by SQLAlchemy when dropping constraints on MSSQL regarding statement caching.
    Source code(tar.gz)
    Source code(zip)
  • rel_1_7_5(Nov 11, 2021)

    1.7.5

    Released: November 11, 2021

    bug

    • [bug] [tests] Adjustments to the test suite to accommodate for error message changes occurring as of SQLAlchemy 1.4.27.
    Source code(tar.gz)
    Source code(zip)
  • rel_1_7_4(Oct 6, 2021)

    1.7.4

    Released: October 6, 2021

    bug

    • [bug] [regression] Fixed a regression that prevented the use of post write hooks on python version lower than 3.9

      References: #934

    • [bug] [environment] Fixed issue where the MigrationContext.autocommit_block() feature would fail to function when using a SQLAlchemy engine using 2.0 future mode.

      References: #944

    Source code(tar.gz)
    Source code(zip)
  • rel_1_7_3(Sep 17, 2021)

    1.7.3

    Released: September 17, 2021

    bug

    • [bug] [mypy] Fixed type annotations for the "constraint_name" argument of operations create_primary_key(), create_foreign_key(). Pull request courtesy TilmanK.

      References: #914

    Source code(tar.gz)
    Source code(zip)
  • rel_1_7_2(Sep 17, 2021)

    1.7.2

    Released: September 17, 2021

    bug

    • [bug] [typing] Added missing attributes from context stubs.

      References: #900

    • [bug] [mypy] Fixed an import in one of the .pyi files that was triggering an assertion error in some versions of mypy.

      References: #897

    • [bug] [ops] [regression] Fixed issue where registration of custom ops was prone to failure due to the registration process running exec() on generated code that as of the 1.7 series includes pep-484 annotations, which in the case of end user code would result in name resolution errors when the exec occurs. The logic in question has been altered so that the annotations are rendered as forward references so that the exec() can proceed.

      References: #920

    Source code(tar.gz)
    Source code(zip)
  • rel_1_7_1(Aug 30, 2021)

    1.7.1

    Released: August 30, 2021

    bug

    • [bug] [installation] Corrected "universal wheel" directive in setup.cfg so that building a wheel does not target Python 2. The PyPi files index for 1.7.0 was corrected manually. Pull request courtesy layday.

      References: #893

    • [bug] [pep484] Fixed issue in generated .pyi files where default values for Optional arguments were missing, thereby causing mypy to consider them as required.

      References: #895

    • [bug] [batch] [regression] Fixed regression in batch mode due to #883 where the "auto" mode of batch would fail to accommodate any additional migration directives beyond encountering an add_column() directive, due to a mis-application of the conditional logic that was added as part of this change, leading to "recreate" mode not being used in cases where it is required for SQLite such as for unique constraints.

      References: #896

    Source code(tar.gz)
    Source code(zip)
  • rel_1_7_0(Aug 30, 2021)

    1.7.0

    Released: August 30, 2021

    changed

    • [changed] [installation] Alembic 1.7 now supports Python 3.6 and above; support for prior versions including Python 2.7 has been dropped.

    • [changed] [installation] Make the python-dateutil library an optional dependency. This library is only required if the timezone option is used in the Alembic configuration. An extra require named tz is available with pip install alembic[tz] to install it.

      References: #674

    • [changed] [installation] The dependency on pkg_resources which is part of setuptools has been removed, so there is no longer any runtime dependency on setuptools. The functionality has been replaced with importlib.metadata and importlib.resources which are both part of Python std.lib, or via pypy dependency importlib-metadata for Python version < 3.8 and importlib-resources for Python version < 3.9 (while importlib.resources was added to Python in 3.7, it did not include the "files" API until 3.9).

      References: #885

    feature

    • [feature] [environment] Enhance version_locations parsing to handle paths containing spaces. The new configuration option version_path_separator specifies the character to use when splitting the version_locations string. The default for new configurations is version_path_separator = os, which will use os.pathsep (e.g., ; on Windows).

      References: #842

    • [feature] [tests] Created a "test suite" similar to the one for SQLAlchemy, allowing developers of third-party dialects to test their code against a set of Alembic tests that have been specially selected to exercise back-end database operations. At the time of release, third-party dialects that have adopted the Alembic test suite to verify compatibility include CockroachDB and SAP ASE (Sybase).

      References: #855

    • [feature] [general] pep-484 type annotations have been added throughout the library. Additionally, stub .pyi files have been added for the "dynamically" generated Alembic modules alembic.op and alembic.config, which include complete function signatures and docstrings, so that the functions in these namespaces will have both IDE support (vscode, pycharm, etc) as well as support for typing tools like Mypy. The files themselves are statically generated from their source functions within the source tree.

    usecase

    • [usecase] [batch] Named CHECK constraints are now supported by batch mode, and will automatically be part of the recreated table assuming they are named. They also can be explicitly dropped using op.drop_constraint(). For "unnamed" CHECK constraints, these are still skipped as they cannot be distinguished from the CHECK constraints that are generated by the Boolean and Enum datatypes.

      Note that this change may require adjustments to migrations that drop or rename columns which feature an associated named check constraint, such that an additional op.drop_constraint() directive should be added for that named constraint as there will no longer be an associated column for it; for the Boolean and Enum datatypes, an existing_type keyword may be passed to BatchOperations.drop_constraint as well.

      References: #884

    bug

    • [bug] [operations] Fixed regression due to #803 where the .info and .comment attributes of Table would be lost inside of the DropTableOp class, which when "reversed" into a CreateTableOp would then have lost these elements. Pull request courtesy Nicolas CANIART.

      References: #879

    • [bug] [batch] [sqlite] Batch "auto" mode will now select for "recreate" if the add_column() operation is used on SQLite, and the column itself meets the criteria for SQLite where ADD COLUMN is not allowed, in this case a functional or parenthesized SQL expression or a Computed (i.e. generated) column.

      References: #883

    • [bug] [commands] Re-implemented the python-editor dependency as a small internal function to avoid the need for external dependencies.

      References: #856

    • [bug] [postgresql] Fixed issue where usage of the PostgreSQL postgresql_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. The issue is equivalent to the SQL Server issue fixed in #513. Pull request courtesy Steven Bronson.

      References: #874

    Source code(tar.gz)
    Source code(zip)
  • rel_1_6_5(May 27, 2021)

    1.6.5

    Released: May 27, 2021

    bug

    • [bug] [autogenerate] Fixed issue where dialect-specific keyword arguments within the DropIndex operation directive would not render in the autogenerated Python code. As support was improved for adding dialect specific arguments to directives as part of #803, in particular arguments such as "postgresql_concurrently" which apply to the actual create/drop of the index, support was needed for these to render even in a drop index operation. Pull request courtesy Jet Zhou.

      References: #849

    Source code(tar.gz)
    Source code(zip)
  • rel_1_6_4(May 24, 2021)

    1.6.4

    Released: May 24, 2021

    bug

    • [bug] [op directives] [regression] Fixed regression caused by just fixed #844 that scaled back the filter for unique=True/index=True too far such that these directives no longer worked for the op.create_table() op, this has been fixed.

      References: #848

    Source code(tar.gz)
    Source code(zip)
  • rel_1_6_3(May 21, 2021)

    1.6.3

    Released: May 21, 2021

    bug

    • [bug] [autogenerate] [regression] Fixed 1.6-series regression where UniqueConstraint and to a lesser extent Index objects would be doubled up in the generated model when the unique=True / index=True flags were used.

      References: #844

    • [bug] [autogenerate] Fixed a bug where paths defined in post-write hook options would be wrongly escaped in non posix environment (Windows).

      References: #839

    • [bug] [regression] [versioning] Fixed regression where a revision file that contained its own down revision as a dependency would cause an endless loop in the traversal logic.

      References: #843

    Source code(tar.gz)
    Source code(zip)
  • rel_1_6_2(May 7, 2021)

    1.6.2

    Released: May 6, 2021

    bug

    • [bug] [regression] [versioning] Fixed additional regression nearly the same as that of #838 just released in 1.6.1 but within a slightly different codepath, where "alembic downgrade head" (or equivalent) would fail instead of iterating no revisions.

      References: #839

    Source code(tar.gz)
    Source code(zip)
  • rel_1_6_1(May 6, 2021)

    1.6.1

    Released: May 6, 2021

    bug

    • [bug] [regression] [versioning] Fixed regression in new revisioning traversal where "alembic downgrade base" would fail if the database itself were clean and unversioned; additionally repairs the case where downgrade would fail if attempting to downgrade to the current head that is already present.

      References: #838

    Source code(tar.gz)
    Source code(zip)
  • rel_1_6_0(May 3, 2021)

    1.6.0

    Released: May 3, 2021

    feature

    • [feature] [autogenerate] Fix the documentation regarding the default command-line argument position of the revision script filename within the post-write hook arguments. Implement a REVISION_SCRIPT_FILENAME token, enabling the position to be changed. Switch from str.split() to shlex.split() for more robust command-line argument parsing.

      References: #819

    • [feature] Implement a .cwd (current working directory) suboption for post-write hooks (of type console_scripts). This is useful for tools like pre-commit, which rely on the working directory to locate the necessary config files. Add pre-commit as an example to the documentation. Minor change: rename some variables from ticket #819 to improve readability.

      References: #822

    bug

    • [bug] [autogenerate] Refactored the implementation of MigrateOperation constructs such as CreateIndexOp, CreateTableOp, etc. so that they no longer rely upon maintaining a persistent version of each schema object internally; instead, the state variables of each operation object will be used to produce the corresponding construct when the operation is invoked. The rationale is so that environments which make use of operation-manipulation schemes such as those those discussed in autogen_rewriter are better supported, allowing end-user code to manipulate the public attributes of these objects which will then be expressed in the final output, an example is some_create_index_op.kw["postgresql_concurrently"] = True.

      Previously, these objects when generated from autogenerate would typically hold onto the original, reflected element internally without honoring the other state variables of each construct, preventing the public API from working.

      References: #803

    • [bug] [environment] Fixed regression caused by the SQLAlchemy 1.4/2.0 compatibility switch where calling .rollback() or .commit() explicitly within the context.begin_transaction() context manager would cause it to fail when the block ended, as it did not expect that the transaction was manually closed.

      References: #829

    • [bug] [autogenerate] Improved the rendering of op.add_column() operations when adding multiple columns to an existing table, so that the order of these statements matches the order in which the columns were declared in the application's table metadata. Previously the added columns were being sorted alphabetically.

      References: #827

    • [bug] [versioning] The algorithm used for calculating downgrades/upgrades/iterating revisions has been rewritten, to resolve ongoing issues of branches not being handled consistently particularly within downgrade operations, as well as for overall clarity and maintainability. This change includes that a deprecation warning is emitted if an ambiguous command such as "downgrade -1" when multiple heads are present is given.

      In particular, the change implements a long-requested use case of allowing downgrades of a single branch to a branchpoint.

      Huge thanks to Simon Bowly for their impressive efforts in successfully tackling this very difficult problem.

      References: #464, #765

    • [bug] [batch] Added missing batch_op.create_table_comment(), batch_op.drop_table_comment() directives to batch ops.

      References: #799

    Source code(tar.gz)
    Source code(zip)
  • rel_1_5_8(Mar 23, 2021)

    1.5.8

    Released: March 23, 2021

    bug

    • [bug] [environment] Fixed regression caused by SQLAlchemy 1.4 where the "alembic current" command would fail due to changes in the URL object.

      References: #816

    Source code(tar.gz)
    Source code(zip)
  • rel_1_5_7(Mar 11, 2021)

    1.5.7

    Released: March 11, 2021

    bug

    • [bug] [autogenerate] Adjusted the recently added EnvironmentContext.configure.include_name hook to accommodate for additional object types such as "views" that don't have a parent table, to support third party recipes and extensions. Pull request courtesy Oliver Rice.

      References: #813

    Source code(tar.gz)
    Source code(zip)
  • rel_1_5_6(Mar 5, 2021)

    1.5.6

    Released: March 5, 2021

    bug

    • [bug] [mssql] [operations] Fixed bug where the "existing_type" parameter, which the MSSQL dialect requires in order to change the nullability of a column in the absence of also changing the column type, would cause an ALTER COLUMN operation to incorrectly render a second ALTER statement without the nullability if a new type were also present, as the MSSQL-specific contract did not anticipate all three of "nullability", "type_" and "existing_type" being sent at the same time.

      References: #812

    misc

    • [template] Add async template to Alembic to bootstrap environments that use async DBAPI. Updated the cookbook to include a migration guide on how to adapt an existing enviroment for use with DBAPI drivers.
    Source code(tar.gz)
    Source code(zip)
  • rel_1_5_5(Feb 20, 2021)

    1.5.5

    Released: February 20, 2021

    bug

    • [bug] Adjusted the use of SQLAlchemy's ".copy()" internals to use "._copy()" for version 1.4.0, as this method is being renamed.

    • [bug] [environment] Added new config file option prepend_sys_path, which is a series of paths that will be prepended to sys.path; the default value in newly generated alembic.ini files is ".". This fixes a long-standing issue where for some reason running the alembic command line would not place the local "." path in sys.path, meaning an application locally present in "." and importable through normal channels, e.g. python interpreter, pytest, etc. would not be located by Alembic, even though the env.py file is loaded relative to the current path when alembic.ini contains a relative path. To enable for existing installations, add the option to the alembic.ini file as follows:

      sys.path path, will be prepended to sys.path if present.

      defaults to the current working directory.

      prepend_sys_path = .References: #797

    Source code(tar.gz)
    Source code(zip)
  • rel_1_5_4(Feb 3, 2021)

    1.5.4

    Released: February 3, 2021

    bug

    • [bug] [versioning] Fixed bug in versioning model where a downgrade across a revision with a dependency on another branch, yet an ancestor is also dependent on that branch, would produce an erroneous state in the alembic_version table, making upgrades impossible without manually repairing the table.

      References: #789

    Source code(tar.gz)
    Source code(zip)
  • rel_1_5_3(Jan 29, 2021)

    1.5.3

    Released: January 29, 2021

    bug

    • [bug] [autogenerate] Changed the default ordering of "CREATE" and "DROP" statements indexes and unique constraints within the autogenerate process, so that for example in an upgrade() operation, a particular index or constraint that is to be replaced such as for a casing convention change will not produce any naming conflicts. For foreign key constraint objects, this is already how constraints are ordered, and for table objects, users would normally want to use Operations.rename_table() in any case.

      References: #786

    • [bug] [autogenerate] [mssql] Fixed assorted autogenerate issues with SQL Server:

      -   ignore default reflected identity on primary_key columns
      
      -   improve server default comparison
      

      References: #787

    • [bug] [autogenerate] [mysql] Fixed issue where autogenerate rendering of op.alter_column() would fail to include MySQL existing_nullable=False if the column were part of a primary key constraint within the table metadata.

      References: #788

    Source code(tar.gz)
    Source code(zip)
  • rel_1_5_2(Jan 20, 2021)

    1.5.2

    Released: January 20, 2021

    bug

    • [bug] [regression] [versioning] Fixed regression where new "loop detection" feature introduced in #757 produced false positives for revision names that have overlapping substrings between revision number and down revision and/or dependency, if the downrev/dependency were not in sequence form.

      References: #784

    • [bug] [environment] Fixed regression where Alembic would fail to create a transaction properly if the sqlalchemy.engine.Connection were a so-called "branched" connection, that is, one where the .connect() method had been called to create a "sub" connection.

      References: #782

    Source code(tar.gz)
    Source code(zip)
  • rel_1_5_1(Jan 19, 2021)

    1.5.1

    Released: January 19, 2021

    bug

    • [bug] [commands] [installation] Fixed installation issue where the "templates" directory was not being installed, preventing commands like "list_templates" and "init" from working.

      References: #780

    Source code(tar.gz)
    Source code(zip)
  • rel_1_5_0(Jan 18, 2021)

    1.5.0

    Released: January 18, 2021

    changed

    • [changed] [environment] To accommodate SQLAlchemy 1.4 and 2.0, the migration model now no longer assumes that the SQLAlchemy Connection will autocommit an individual operation. This essentially means that for databases that use non-transactional DDL (pysqlite current driver behavior, MySQL), there is still a BEGIN/COMMIT block that will surround each individual migration. Databases that support transactional DDL should continue to have the same flow, either per migration or per-entire run, depending on the value of the Environment.configure.transaction_per_migration flag.

    • [changed] [environment] A CommandError is raised if a sqlalchemy.engine.Engine is passed to the MigrationContext.configure() method instead of a sqlalchemy.engine.Connection object. Previously, this would be a warning only.

    • [changed] Alembic 1.5.0 now supports Python 2.7 and Python 3.6 and above, as well as SQLAlchemy 1.3.0 and above. Support is removed for Python 3 versions prior to 3.6 and SQLAlchemy versions prior to the 1.3 series.

      References: #748

    feature

    • [feature] [autogenerate] Added new hook EnvironmentContext.configure.include_name, which complements the EnvironmentContext.configure.include_object hook by providing a means of preventing objects of a certain name from being autogenerated before the SQLAlchemy reflection process takes place, and notably includes explicit support for passing each schema name when EnvironmentContext.configure.include_schemas is set to True. This is most important especially for enviroments that make use of EnvironmentContext.configure.include_schemas where schemas are actually databases (e.g. MySQL) in order to prevent reflection sweeps of the entire server.

      References: #650

    • [feature] [versioning] The revision tree is now checked for cycles and loops between revision files when the revision environment is loaded up. Scenarios such as a revision pointing to itself, or a revision that can reach itself via a loop, are handled and will raise the CycleDetected exception when the environment is loaded (expressed from the Alembic commandline as a failure message and nonzero return code). Previously, these situations were silently ignored up front, and the behavior of revision traversal would either be silently incorrect, or would produce errors such as RangeNotAncestorError. Pull request courtesy Koichiro Den.

      References: #757

    bug

    • [bug] [operations] Modified the add_column() operation such that the Column object in use is shallow copied to a new instance if that Column is already attached to a table() or Table. This accommodates for the change made in SQLAlchemy issue #5618 which prohibits a Column from being associated with multiple table() objects. This resumes support for using a Column inside of an Alembic operation that already refers to a parent table() or Table as well as allows operation objects just autogenerated to work.

      References: #753

    • [bug] [autogenerate] Added rendering for the Table.prefixes element to autogenerate so that the rendered Python code includes these directives. Pull request courtesy Rodrigo Ce Moretto.

      References: #721

    • [bug] [batch] Added missing "create comment" feature for columns that are altered in batch migrations.

      References: #761

    • [bug] [batch] Made an adjustment to the PostgreSQL dialect to allow it to work more effectively in batch mode, where a datatype like Boolean or non-native Enum that may have embedded rules to generate CHECK constraints will be more correctly handled in that these constraints usually will not have been generated on the PostgreSQL backend; previously it would inadvertently assume they existed unconditionally in a special PG-only "drop constraint" step.

      References: #773

    usecase

    • [usecase] [operations] Added support for rendering of "identity" elements on Column objects, supported in SQLAlchemy via the Identity element introduced in version 1.4.

      Adding columns with identity is supported on PostgreSQL, MSSQL and Oracle. Changing the identity options or removing it is supported only on PostgreSQL and Oracle.

      References: #730

    • [usecase] [commands] Add __main__.py file to alembic package to support invocation with python -m alembic.

    removed

    • [removed] [autogenerate] The long deprecated EnvironmentContext.configure.include_symbol hook is removed. The EnvironmentContext.configure.include_object and EnvironmentContext.configure.include_name hooks both achieve the goals of this hook.

    • [removed] [commands] Removed deprecated --head_only option to the alembic current command

    • [removed] [operations] Removed legacy parameter names from operations, these have been emitting warnings since version 0.8. In the case that legacy version files have not yet been updated, these can be modified directly in order to maintain compatibility:

      -   `Operations.drop_constraint()` - "type" (use "type_") and "name"
          (use "constraint_name")
      
      -   `Operations.create_primary_key()` - "cols" (use "columns") and
          "name" (use "constraint_name")
      
      -   `Operations.create_unique_constraint()` - "name" (use
          "constraint_name"), "source" (use "table_name") and "local_cols" (use
          "columns")
      
      -   `Operations.batch_create_unique_constraint()` - "name" (use
          "constraint_name")
      
      -   `Operations.create_foreign_key()` - "name" (use "constraint_name"),
          "source" (use "source_table"), "referent" (use "referent_table")
      
      -   `Operations.batch_create_foreign_key()` - "name" (use
          "constraint_name"), "referent" (use "referent_table")
      
      -   `Operations.create_check_constraint()` - "name" (use
          "constraint_name"), "source" (use "table_name")
      
      -   `Operations.batch_create_check_constraint()` - "name" (use
          "constraint_name")
      
      -   `Operations.create_index()` - "name" (use "index_name")
      
      -   `Operations.drop_index()` - "name" (use "index_name"), "tablename"
          (use "table_name")
      
      -   `Operations.batch_drop_index()` - "name" (use "index_name"),
      
      -   `Operations.create_table()` - "name" (use "table_name")
      
      -   `Operations.drop_table()` - "name" (use "table_name")
      
      -   `Operations.alter_column()` - "name" (use "new_column_name")
      
    Source code(tar.gz)
    Source code(zip)
  • rel_1_4_3(Sep 11, 2020)

    1.4.3

    Released: September 11, 2020

    bug

    • [bug] [batch] [sqlite] Added support to drop named CHECK constraints that are specified as part of a column, rather than table wide. Previously, only constraints associated with the table were considered.

      References: #711

    • [bug] [mysql] [ops] Fixed issue where the MySQL dialect would not correctly render the server default of a column in an alter operation, if the operation were programmatically generated from an autogenerate pass as it would not accommodate for the full structure of the DefaultClause construct.

      References: #736

    • [bug] [batch] [sqlite] Fixed issue where the CAST applied to a JSON column when copying a SQLite table during batch mode would cause the data to be lost, as SQLite's CAST with JSON appears to convert the data to the value "0". The CAST is now skipped in a dialect-specific manner, including for JSON columns on SQLite. Pull request courtesy Sebastián Ramírez.

      References: #697

    • [bug] [commands] The alembic current command no longer creates an alembic_version table in the database if one does not exist already, returning no version as the current version. This allows checking for migrations in parallel without introducing race conditions. Pull request courtesy Nikolay Edigaryev.

      References: #694

    • [bug] [batch] Fixed issue where columns in a foreign-key referenced table would be replaced with null-type columns during a batch operation; while this did not generally have any side effects, it could theoretically impact a batch operation that also targets that table directly and also would interfere with future changes to the .append_column() method to disallow implicit replacement of columns.

    • [bug] [mssql] Fixed issue where the mssql_drop_foreign_key=True flag on op.drop_column would lead to incorrect syntax error due to a typo in the SQL emitted, same typo was present in the test as well so it was not detected. Pull request courtesy Oleg Shigorin.

      References: #716

    Source code(tar.gz)
    Source code(zip)
  • rel_1_4_2(Mar 19, 2020)

    1.4.2

    Released: March 19, 2020

    bug

    • [bug] [tests] Fixed an issue that prevented the test suite from running with the recently released py.test 5.4.0.

      References: #668

    • [bug] [autogenerate] [mysql] Fixed more false-positive failures produced by the new "compare type" logic first added in #605, particularly impacting MySQL string types regarding flags such as "charset" and "collation".

      References: #617

    • [bug] [op directives] [oracle] Fixed issue in Oracle backend where a table RENAME with a schema-qualified name would include the schema in the "to" portion, which is rejected by Oracle.

      References: #670

    usecase

    • [usecase] [autogenerate] Adjusted autogen comparison to accommodate for backends that support computed column reflection, dependent on SQLAlchemy version 1.3.16 or higher. This emits a warning if the SQL expression inside of a Computed value changes between the metadata and the database, as these expressions can't be changed without dropping and recreating the column.

      References: #669

    Source code(tar.gz)
    Source code(zip)
  • rel_1_4_1(Mar 2, 2020)

    1.4.1

    Released: March 1, 2020

    bug

    • [bug] [autogenerate] Fixed regression caused by the new "type comparison" logic introduced in 1.4 as part of #605 where comparisons of MySQL "unsigned integer" datatypes would produce false positives, as the regular expression logic was not correctly parsing the "unsigned" token when MySQL's default display width would be returned by the database. Pull request courtesy Paul Becotte.

      References: #661

    • [bug] [environment] Error message for "path doesn't exist" when loading up script environment now displays the absolute path. Pull request courtesy Rowan Hart.

      References: #663

    • [bug] [autogenerate] Fixed regression in 1.4.0 due to #647 where unique constraint comparison with mixed case constraint names while not using a naming convention would produce false positives during autogenerate.

      References: #654

    • [bug] [environment] The check for matched rowcount when the alembic_version table is updated or deleted from is now conditional based on whether or not the dialect supports the concept of "rowcount" for UPDATE or DELETE rows matched. Some third party dialects do not support this concept. Pull request courtesy Ke Zhu.

    • [bug] [operations] Fixed long-standing bug where an inline column CHECK constraint would not be rendered within an "ADD COLUMN" operation. The DDL compiler is now consulted for inline constraints within the Operations.add_column() method as is done for regular CREATE TABLE operations.

      References: #655

    Source code(tar.gz)
    Source code(zip)
Owner
SQLAlchemy
The Database Toolkit and Object Relational Mapper
SQLAlchemy
dbd is a database prototyping tool that enables data analysts and engineers to quickly load and transform data in SQL databases.

dbd: database prototyping tool dbd is a database prototyping tool that enables data analysts and engineers to quickly load and transform data in SQL d

Zdenek Svoboda 47 Dec 7, 2022
MySQL database connector for Python (with Python 3 support)

mysqlclient This project is a fork of MySQLdb1. This project adds Python 3 support and fixed many bugs. PyPI: https://pypi.org/project/mysqlclient/ Gi

PyMySQL 2.2k Dec 25, 2022
PostgreSQL database access simplified

Queries: PostgreSQL Simplified Queries is a BSD licensed opinionated wrapper of the psycopg2 library for interacting with PostgreSQL. The popular psyc

Gavin M. Roy 251 Oct 25, 2022
A fast PostgreSQL Database Client Library for Python/asyncio.

asyncpg -- A fast PostgreSQL Database Client Library for Python/asyncio asyncpg is a database interface library designed specifically for PostgreSQL a

magicstack 5.8k Dec 31, 2022
aiopg is a library for accessing a PostgreSQL database from the asyncio

aiopg aiopg is a library for accessing a PostgreSQL database from the asyncio (PEP-3156/tulip) framework. It wraps asynchronous features of the Psycop

aio-libs 1.3k Jan 3, 2023
aiomysql is a library for accessing a MySQL database from the asyncio

aiomysql aiomysql is a "driver" for accessing a MySQL database from the asyncio (PEP-3156/tulip) framework. It depends on and reuses most parts of PyM

aio-libs 1.5k Jan 3, 2023
Async database support for Python. 🗄

Databases Databases gives you simple asyncio support for a range of databases. It allows you to make queries using the powerful SQLAlchemy Core expres

Encode 3.2k Dec 30, 2022
The Database Toolkit for Python

SQLAlchemy The Python SQL Toolkit and Object Relational Mapper Introduction SQLAlchemy is the Python SQL toolkit and Object Relational Mapper that giv

SQLAlchemy 6.5k Jan 1, 2023
MySQL database connector for Python (with Python 3 support)

mysqlclient This project is a fork of MySQLdb1. This project adds Python 3 support and fixed many bugs. PyPI: https://pypi.org/project/mysqlclient/ Gi

PyMySQL 2.2k Dec 25, 2022
Python interface to Oracle Database conforming to the Python DB API 2.0 specification.

cx_Oracle version 8.2 (Development) cx_Oracle is a Python extension module that enables access to Oracle Database. It conforms to the Python database

Oracle 841 Dec 21, 2022
A HugSQL-inspired database library for Python

PugSQL PugSQL is a simple Python interface for using parameterized SQL, in files. See pugsql.org for the documentation. To install: pip install pugsql

Dan McKinley 558 Dec 24, 2022
PostgreSQL database adapter for the Python programming language

psycopg2 - Python-PostgreSQL Database Adapter Psycopg is the most popular PostgreSQL database adapter for the Python programming language. Its main fe

The Psycopg Team 2.8k Jan 5, 2023
The JavaScript Database, for Node.js, nw.js, electron and the browser

The JavaScript Database Embedded persistent or in memory database for Node.js, nw.js, Electron and browsers, 100% JavaScript, no binary dependency. AP

Louis Chatriot 13.2k Jan 2, 2023
Query multiple mongoDB database collections easily

leakscoop Perform queries across multiple MongoDB databases and collections, where the field names and the field content structure in each database ma

bagel 5 Jun 24, 2021
A tiny python web application based on Flask to set, get, expire, delete keys of Redis database easily with direct link at the browser.

First Redis Python (CRUD) A tiny python web application based on Flask to set, get, expire, delete keys of Redis database easily with direct link at t

Max Base 9 Dec 24, 2022
Class to connect to XAMPP MySQL Database

MySQL-DB-Connection-Class Class to connect to XAMPP MySQL Database Basta fazer o download o mysql_connect.py e modificar os parâmetros que quiser. E d

Alexandre Pimentel 4 Jul 12, 2021
A Relational Database Management System for a miniature version of Twitter written in MySQL with CLI in python.

Mini-Twitter-Database This was done as a database design course project at Amirkabir university of technology. This is a relational database managemen

Ali 12 Nov 23, 2022
Sample code to extract data directly from the NetApp AIQUM MySQL Database

This sample code shows how to connect to the AIQUM Database and pull user quota details from it. AIQUM Requirements: 1. AIQUM 9.7 or higher. 2. An

null 1 Nov 8, 2021
Database connection pooler for Python

Nimue Strange women lying in ponds distributing swords is no basis for a system of government! --Dennis, Peasant Nimue is a database connection pool f

null 1 Nov 9, 2021