Mike Bayer [Wed, 29 Oct 2025 13:33:42 +0000 (09:33 -0400)]
remove DB-based skips on non-backend tests
for tests that are testing for SQL compilation only,
there's no need to limit based on DB backend since we aren't
using it. this avoids the awkward situation where tests like
test_sqlite.py -> test_create_table_with_comment_ignored would
be skipped when running the test suite against sqlite, but would
run just fine when running against any other DB (because those DBs
dont have a comment limitation and the test is just a compilation
test).
Kim Wooseok [Tue, 28 Oct 2025 12:05:24 +0000 (08:05 -0400)]
Add colon (:) to invalid char for revision name add unittest
Disallow ':' character in custom revision identifiers. Previously, using a
colon in a revision ID (e.g., 'REV:1') would create the revision, however
revisions with colons in them are not correctly interpreted by other
commands, as it overlaps with the revision range syntax. Pull request
courtesy Kim Wooseok with original implementation by Hrushikesh Patil.
Stefan Scherfke [Tue, 28 Oct 2025 12:06:31 +0000 (08:06 -0400)]
Add "--check-heads" option to "current" command
Added :paramref:`.command.current.check_heads` parameter to
:func:`.command.current` command, available from the command line via the
``--check-heads`` option to ``alembic current``. This tests if all head
revisions are applied to the database and raises :class:`.DatabaseNotAtHead`
(or from the command line, exits with a non-zero exit code) if this is not
the case. The parameter operates equvialently to the cookbook recipe
:ref:`cookbook_check_heads`. Pull request courtesy Stefan Scherfke.
Mike Bayer [Sat, 11 Oct 2025 17:30:07 +0000 (13:30 -0400)]
more nox
* add support for backend-only
* main runner only runs one database at a time, there is no multiple
db for one pytest run feature here
* use match/case!
Mike Bayer [Thu, 9 Oct 2025 13:21:16 +0000 (09:21 -0400)]
remove suite name changes
the junit plugin doesnt need suites to have distinct names.
it is actually merging correctly, the reason for lots of noise
is that the different suites have lots of skips for the
"backend" marked suites. will fix this in pytestplugin
Mike Bayer [Mon, 6 Oct 2025 20:01:03 +0000 (16:01 -0400)]
test updates
* remove .coveragerc since this produces warnings vs. pytest-cov
* use junitparser to rename the suite inside each junit file. I think
jenkins junit reads multiple files but they need to have distinct
suite names to show up (or distinct test names, but we dont have that
here).
Fixed issue where new pyproject.toml config would fail to parse the integer
value used for the ``truncate_slug_length`` parameter. Pull request
courtesy Luís Henrique Allebrandt Schunemann.
Fixed Python-side autogenerate rendering of index expressions in MySQL
dialect by aligning it with SQLAlchemy's MySQL index expression rules. Pull
request courtesy david-fed.
Mike Bayer [Wed, 9 Jul 2025 18:57:11 +0000 (14:57 -0400)]
add boolean interpretation to config
Fixed issue in new ``pyproject.toml`` support where boolean values, such as
those used for the ``recursive_version_locations`` and ``sourceless``
configuration parameters, would not be accepted.
This hook type is almost identical to the console_scripts hook, except
it's running `python -m black` instead of using black's console_script.
It is mainly useful for tools without console scripts (e.g. ruff), but
has semantics closer to the console_scripts hook in that it finds the
ruff module available to the running interpreter instead of finding
an executable by path.
Fixed the rendering of ``server_default=FetchedValue()`` to ensure it is
preceded by the ``sa.`` prefix in the migration script. Pull request
courtesy david-fed.
Mike Bayer [Tue, 8 Jul 2025 14:05:56 +0000 (10:05 -0400)]
fix metadata requirement in fk render; remove column.copy()
Fixed autogenerate rendering bug which failed to render foreign key
constraints local to a :class:`.CreateTableOp` object if it did not refer
to a ``MetaData`` collection via a private constructor argument that would
not ordinarily be passed in user-defined rewriter recipes, including ones
in the Alembic cookbook section of the docs.
Also removed the use of column.copy() from the CreateTableOp rewriter
recipe and added a new test for this recipe which includes a table with
an FK. it's not clear why copy() was needed here and if we get more
reports of issues, we can add to this test suite and adjust.
Mike Bayer [Tue, 24 Jun 2025 18:04:56 +0000 (14:04 -0400)]
try flake8-import-order 0.19.2
the big new thang is that it is doing import order checks inside of
TYPE_CHECKING blocks. Introduces some new codes that we
enthusiastically add to our ignore list.
Justin Malin [Thu, 12 Jun 2025 19:56:36 +0000 (15:56 -0400)]
[Fixes #1671] Passthrough `dialect_kwargs` to `ops.create_foreign_key()`
<!-- Provide a general summary of your proposed changes in the Title field above -->
### Description
<!-- Describe your changes in detail -->
Fixes #1671
SqlAlchemy supports adding dialect kwargs for foreign keys, as does `op.create_foreign_key()`, but the renderer for `ops.CreateForeignKeyOp` does not pass through `dialect_kwargs`. An example of this is `postgresql_not_valid`.
### Checklist
<!-- go over following points. check them with an `x` if they do apply, (they turn into clickable checkboxes once the PR is submitted, so no need to do everything at once)
-->
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.
Mike Bayer [Sun, 8 Jun 2025 20:14:19 +0000 (16:14 -0400)]
updates for mypy 1.16
some errors go away, others come in. basically moving
ignores around. need to pin to 1.16 at the lowest as these
would now fail on earlier mypy versions
Simon Tas [Thu, 29 May 2025 00:11:58 +0000 (20:11 -0400)]
allow tuple type in down_revision in migration templates
<!-- Provide a general summary of your proposed changes in the Title field above -->
FIXES #1665
Currently the type of `down_revision` in migration templates is `Union[str, None]`. However, when you generate a migration using `alembic merge heads` it will generate a migration with a tuple of strings in `down_revision` which causes a type error.
### Description
f.e. when you have 2 heads and run `alembic merge heads` you will get a migration that looks like this:
which will give a type error with type checkers like mypy and pyright. This change fixes this. From the code it seems like just like `branch_labels` and `depends_on` the `down_revision` is first casted to a tuple if needed so typing it as `Sequence[str]` and not `Tuple[str, ...]` should be safe.
### Checklist
<!-- go over following points. check them with an `x` if they do apply, (they turn into clickable checkboxes once the PR is submitted, so no need to do everything at once)
-->
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.
Mike Bayer [Wed, 21 May 2025 21:14:37 +0000 (17:14 -0400)]
honor get_templates_path() first
Fixed regression caused by the ``pathlib`` refactoring that removed the use
of :meth:`.Config.get_template_directory` as the canonical source of
templates; the method is still present however it no longer would be
consulted for a custom config subclass, as was the case with flask-migrate.
Fixed regression caused by the ``pathlib`` refactoring where the "missing
template" error message failed to render the name of the template that
could not be found.
Mike Bayer [Wed, 21 May 2025 14:09:46 +0000 (10:09 -0400)]
ensure conv is applied to all reflected index and constraint names
The autogenerate process will now apply the :meth:`.Operations.f` modifier
to the names of all constraints and indexes that are reflected from the
target database when generating migrations, which has the effect that these
names will not have any subsequent naming conventions applied to them when
the migration operations proceed. As reflected objects already include the
exact name that's present in the database, these names should not be
modified. The fix repairs the issue when using custom naming conventions
which feature the ``%(constraint_name)s`` token would cause names to be
double-processed, leading to errors in migration runs.
Mike Bayer [Wed, 21 May 2025 03:40:33 +0000 (23:40 -0400)]
more tweaks
this is primarily cleanup of the changelog section which is
extensive for this release.
Additionally, limited Config.config_file_name and Config.toml_file_name
to string only when accessed, making use of _preserving_path_as_str()
for these on the parameter side.
Jens Troeger [Tue, 20 May 2025 21:01:45 +0000 (17:01 -0400)]
Replace use of utcnow() with now() for Python 3.13 compatibility, Fixes #1643
Fixed issue where use of deprecated ``utcnow()`` function would generate
warnings. Has been replaced with ``now(UTC)``. Pull request courtesy
Jens Tröger.
Mike Bayer [Tue, 20 May 2025 20:32:31 +0000 (16:32 -0400)]
now get %(here)s to work for all special pyproject config values
batting 1000 here, the %(here)s token was totally not handled
in any of version_locations, prepend_sys_path_paths, post_write_hooks.
All params that definitely need this token.
Mike Bayer [Tue, 20 May 2025 19:17:54 +0000 (15:17 -0400)]
make sure no-ini-file actually works
because Config has an alembic.ini path in it by default, if the file
doesnt exist it will raise when you call get_main_option(). make sure
no alembic function calls upon get_main_option() directly at all so that
configparser is entirely not required
Mike Bayer [Tue, 20 May 2025 14:12:30 +0000 (10:12 -0400)]
use Path.name for split target
some code dealing with .pyc names that needs the first token of the
dot-separated filename is clearer based on path.name, full filename,
rather than .stem
Mike Bayer [Mon, 19 May 2025 17:06:56 +0000 (13:06 -0400)]
use pathlib for file operations across the board
The command, config and script modules now rely on ``pathlib.Path`` for
internal path manipulations, instead of ``os.path()`` operations. Public
API functions that accept string directories and filenames continue to do
so but also accept ``os.PathLike`` objects. Public API functions and
accessors that return paths as strings continue to do so. Private API
functions and accessors, i.e. all those that are prefixed with an
underscore, may now return a Path object rather than a string to indicate
file paths.
Mike Bayer [Mon, 19 May 2025 16:24:44 +0000 (12:24 -0400)]
add autogen render for drop_constraint.if_exists
I've maintained all along that #1650 and #1626 are the same thing
and should have been one big PR. Here we complete the autogen
portion of the #1650 PR that was omitted.
Add support of IF [NOT] EXISTS for ADD/DROP COLUMN in Postgresql
Added :paramref:`.Operations.add_column.if_not_exists` and
:paramref:`.Operations.drop_column.if_exists` to render ``IF [NOT] EXISTS``
for ``ADD COLUMN`` and ``DROP COLUMN`` operations, a feature available on
some database backends such as PostgreSQL, MariaDB, as well as third party
backends. The parameters also support autogenerate rendering allowing them
to be turned on via a custom :class:`.Rewriter`. Pull request courtesy of
Louis-Amaury Chaib (@lachaib).
Mike Bayer [Tue, 13 May 2025 14:14:10 +0000 (10:14 -0400)]
allow pep 621 configuration
Added optional :pep:`621` support to Alembic, where a subset of the
project-centric configuration normally found in the ``alembic.ini`` file
can now be retrieved from the project-wide ``pyproject.toml`` file. A new
init template ``pyproject`` is added which illustrates a basic :pep:`621`
setup. The :pep:`621` feature supports configuration values that are
relevant to code locations and code production only; it does not
accommodate database connectivity, configuration, or logging configuration.
These latter configurational elements remain as elements that can be
present either in the ``alembic.ini`` file, or retrieved elsewhere within
the ``env.py`` file. The change also allows the ``alembic.ini`` file to
be completely optional if the ``pyproject.toml`` file contains a base
alembic configuration section.
<!-- Provide a general summary of your proposed changes in the Title field above -->
### Description
Rendering ExecuteSQLOp did not respect the `alembic_module_prefix` setting due
to having `op.` hard-coded in its template.
This change updates the render logic to use the same
`_alembic_autogenerate_prefix()` as it seems the rest of the ops use.
### 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.
Mike Werezak [Sat, 26 Apr 2025 18:57:24 +0000 (14:57 -0400)]
Add file_path_separator to apply to all path splitting
Added new option to the ConfigParser config (typically via ``alembic.ini``)
``path_separator``. This new option supersedes the previous similar
option ``version_path_separator``. The new ``path_separator`` option
applies to the path splitting mechanism of both the ``version_locations``
option as well as the ``prepend_sys_path`` option, and in newly
rendered ``alembic.ini`` files will use the value ``os``, which means to
use the operating system path separator when splitting these string values
into a list of paths.
The new attribute applies necessary os-dependent path splitting to the
``prepend_sys_path`` option so that windows paths which contain drive
letters with colons are not inadvertently split, whereas previously
os-dependent path splitting were only available for the
``version_locations`` option.
Existing installations that do not have ``path_separator`` present
will continue to make use of ``version_path_separator`` when parsing the
``version_locations`` option, or splitting on spaces / commas if
``version_path_separator`` is also not present. ``prepend_sys_path`` will
continue to be split on spaces/commas/colons if ``path_separator`` is
not present. Under all of these fallback conditions, a deprecation
warning is now emitted encouraging to set ``path_separator``.
Pull request courtesy Mike Werezak.
This change also begins to move some of the role of interpreting
of specific config options into the Config object. This process will
continue as we look to add toml support to config.
Mike Bayer [Wed, 7 May 2025 15:34:49 +0000 (11:34 -0400)]
use pep639
The pyproject.toml configuration has been amended to use the updated
:pep:`639` configuration for license, which eliminates loud deprecation
warnings when building the package. Note this necessarily bumps
setuptools build requirement to 77.0.3.
Also bump black, flake8, see what's coming.
this change is modeled after the same change made in dogpile.cache
which has since been released.
Added new :meth:`.CommandLine.register_command` method to
:class:`.CommandLine`, intended to facilitate adding custom commands to
Alembic's command line tool with minimal code required; previously this
logic was embedded internally and was not publicly accessible. A new
recipe demonstrating this use is added. Pull request courtesy Mikhail
Bulash.
Added :paramref:`.op.drop_constraint.if_exists` parameter to
:func:`.op.drop_constraint` which will render "DROP CONSTRAINT IF EXISTS".
Pull request courtesy Aaron Griffin.
Also attempting to fix unrelated issue w/ test_stubs and python
versions which may be in a separate patch if it can't work here