Skip to content

alembic check fails with invalid volatility value #125

@YaraslauZhylko

Description

@YaraslauZhylko

In versions 0.16.0 and 0.16.1, running alembic checks results in the following error:

2025-08-21T06:18:46.700918Z [info     ] Context impl PostgresqlImpl.   [alembic.runtime.migration]
2025-08-21T06:18:46.701665Z [info     ] Will assume transactional DDL. [alembic.runtime.migration]
statement=None
Traceback (most recent call last):
  File "/home/yaraslau/projects/backend2.0/.venv/bin/alembic", line 8, in <module>
    sys.exit(main())
             ~~~~^^
  File "/home/yaraslau/projects/backend2.0/.venv/lib/python3.13/site-packages/alembic/config.py", line 1016, in main
    CommandLine(prog=prog).main(argv=argv)
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^
  File "/home/yaraslau/projects/backend2.0/.venv/lib/python3.13/site-packages/alembic/config.py", line 1006, in main
    self.run_cmd(cfg, options)
    ~~~~~~~~~~~~^^^^^^^^^^^^^^
  File "/home/yaraslau/projects/backend2.0/.venv/lib/python3.13/site-packages/alembic/config.py", line 940, in run_cmd
    fn(
    ~~^
        config,
        ^^^^^^^
        *[getattr(options, k, None) for k in positional],
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        **{k: getattr(options, k, None) for k in kwarg},
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    )
    ^
  File "/home/yaraslau/projects/backend2.0/.venv/lib/python3.13/site-packages/alembic/command.py", line 363, in check
    script_directory.run_env()
    ~~~~~~~~~~~~~~~~~~~~~~~~^^
  File "/home/yaraslau/projects/backend2.0/.venv/lib/python3.13/site-packages/alembic/script/base.py", line 549, in run_env
    util.load_python_file(self.dir, "env.py")
    ~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^
  File "/home/yaraslau/projects/backend2.0/.venv/lib/python3.13/site-packages/alembic/util/pyfiles.py", line 116, in load_python_file
    module = load_module_py(module_id, path)
  File "/home/yaraslau/projects/backend2.0/.venv/lib/python3.13/site-packages/alembic/util/pyfiles.py", line 136, in load_module_py
    spec.loader.exec_module(module)  # type: ignore
    ~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^
  File "<frozen importlib._bootstrap_external>", line 1026, in exec_module
  File "<frozen importlib._bootstrap>", line 488, in _call_with_frames_removed
  File "/home/yaraslau/projects/backend2.0/migrations/env.py", line 116, in <module>
    run_migrations_online()
    ~~~~~~~~~~~~~~~~~~~~~^^
  File "/home/yaraslau/projects/backend2.0/migrations/env.py", line 113, in run_migrations_online
    asyncio.run(connect_and_do_migrations())
    ~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/yaraslau/.pyenv/versions/3.13.5/lib/python3.13/asyncio/runners.py", line 195, in run
    return runner.run(main)
           ~~~~~~~~~~^^^^^^
  File "/home/yaraslau/.pyenv/versions/3.13.5/lib/python3.13/asyncio/runners.py", line 118, in run
    return self._loop.run_until_complete(task)
           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^
  File "/home/yaraslau/.pyenv/versions/3.13.5/lib/python3.13/asyncio/base_events.py", line 725, in run_until_complete
    return future.result()
           ~~~~~~~~~~~~~^^
  File "/home/yaraslau/projects/backend2.0/migrations/env.py", line 104, in connect_and_do_migrations
    await connection.run_sync(do_migrations)
  File "/home/yaraslau/projects/backend2.0/.venv/lib/python3.13/site-packages/sqlalchemy/ext/asyncio/engine.py", line 887, in run_sync
    return await greenlet_spawn(
           ^^^^^^^^^^^^^^^^^^^^^
        fn, self._proxied, *arg, _require_await=False, **kw
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    )
    ^
  File "/home/yaraslau/projects/backend2.0/.venv/lib/python3.13/site-packages/sqlalchemy/util/_concurrency_py3k.py", line 203, in greenlet_spawn
    result = context.switch(value)
  File "/home/yaraslau/projects/backend2.0/migrations/env.py", line 65, in do_migrations
    context.run_migrations()
    ~~~~~~~~~~~~~~~~~~~~~~^^
  File "<string>", line 8, in run_migrations
  File "/home/yaraslau/projects/backend2.0/.venv/lib/python3.13/site-packages/alembic/runtime/environment.py", line 946, in run_migrations
    self.get_context().run_migrations(**kw)
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^
  File "/home/yaraslau/projects/backend2.0/.venv/lib/python3.13/site-packages/alembic/runtime/migration.py", line 615, in run_migrations
    for step in self._migrations_fn(heads, self):
                ~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^
  File "/home/yaraslau/projects/backend2.0/.venv/lib/python3.13/site-packages/alembic/command.py", line 352, in retrieve_migrations
    revision_context.run_autogenerate(rev, context)
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^
  File "/home/yaraslau/projects/backend2.0/.venv/lib/python3.13/site-packages/alembic/autogenerate/api.py", line 570, in run_autogenerate
    self._run_environment(rev, migration_context, True)
    ~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/yaraslau/projects/backend2.0/.venv/lib/python3.13/site-packages/alembic/autogenerate/api.py", line 617, in _run_environment
    compare._populate_migration_script(
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
        autogen_context, migration_script
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    )
    ^
  File "/home/yaraslau/projects/backend2.0/.venv/lib/python3.13/site-packages/alembic/autogenerate/compare.py", line 66, in _populate_migration_script
    _produce_net_changes(autogen_context, upgrade_ops)
    ~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/yaraslau/projects/relief/backend2.0/.venv/lib/python3.13/site-packages/alembic/autogenerate/compare.py", line 99, in _produce_net_changes
    comparators.dispatch("schema", autogen_context.dialect.name)(
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
        autogen_context, upgrade_ops, schemas
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    )
    ^
  File "/home/yaraslau/projects/backend2.0/.venv/lib/python3.13/site-packages/alembic/util/langhelpers.py", line 310, in go
    fn(*arg, **kw)
    ~~^^^^^^^^^^^^
  File "/home/yaraslau/projects/backend2.0/.venv/lib/python3.13/site-packages/sqlalchemy_declarative_extensions/alembic/function.py", line 26, in _compare_functions
    result = compare_functions(autogen_context.connection, functions)
  File "/home/yaraslau/projects/relief/backend2.0/.venv/lib/python3.13/site-packages/sqlalchemy_declarative_extensions/function/compare.py", line 57, in compare_functions
    raw_existing_functions = get_functions(connection)
  File "/home/yaraslau/projects/backend2.0/.venv/lib/python3.13/site-packages/sqlalchemy_declarative_extensions/sqlalchemy.py", line 49, in dispatch
    return dispatcher(connection, *args, **kwargs)
  File "/home/yaraslau/projects/backend2.0/.venv/lib/python3.13/site-packages/sqlalchemy_declarative_extensions/dialects/postgresql/query.py", line 245, in get_functions_postgresql
    volatility=FunctionVolatility.from_provolatile(f.volatility),
               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^
  File "/home/yaraslau/projects/backend2.0/.venv/lib/python3.13/site-packages/sqlalchemy_declarative_extensions/dialects/postgresql/function.py", line 35, in from_provolatile
    raise ValueError(f"Invalid volatility: {provolatile}")
ValueError: Invalid volatility: b'v'

Migration themselves (alembic upgrade/ alembic downgrade) run correctly without errors.

DB: PostgreSQL 17.4
Python version: 3.13.5
Alembic version: 1.16.4
DB driver: postgresql-asyncpg 0.30.0

Fails both locally and in CI. So this is not a local setup issue.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions