alembic 1.16.0__tar.gz → 1.16.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {alembic-1.16.0/alembic.egg-info → alembic-1.16.2}/PKG-INFO +1 -1
- {alembic-1.16.0 → alembic-1.16.2}/alembic/__init__.py +1 -1
- {alembic-1.16.0 → alembic-1.16.2}/alembic/autogenerate/compare.py +2 -2
- {alembic-1.16.0 → alembic-1.16.2}/alembic/autogenerate/render.py +17 -7
- {alembic-1.16.0 → alembic-1.16.2}/alembic/autogenerate/rewriter.py +2 -2
- {alembic-1.16.0 → alembic-1.16.2}/alembic/command.py +1 -1
- {alembic-1.16.0 → alembic-1.16.2}/alembic/config.py +19 -6
- {alembic-1.16.0 → alembic-1.16.2}/alembic/runtime/environment.py +1 -1
- {alembic-1.16.0 → alembic-1.16.2}/alembic/runtime/migration.py +5 -1
- {alembic-1.16.0 → alembic-1.16.2}/alembic/script/base.py +6 -2
- {alembic-1.16.0 → alembic-1.16.2}/alembic/templates/async/script.py.mako +1 -1
- {alembic-1.16.0 → alembic-1.16.2}/alembic/templates/generic/script.py.mako +1 -1
- {alembic-1.16.0 → alembic-1.16.2}/alembic/templates/multidb/script.py.mako +1 -1
- {alembic-1.16.0 → alembic-1.16.2}/alembic/templates/pyproject/script.py.mako +1 -1
- {alembic-1.16.0 → alembic-1.16.2}/alembic/util/pyfiles.py +4 -2
- {alembic-1.16.0 → alembic-1.16.2/alembic.egg-info}/PKG-INFO +1 -1
- {alembic-1.16.0 → alembic-1.16.2}/docs/_sources/changelog.rst +45 -0
- {alembic-1.16.0/docs/build → alembic-1.16.2/docs/_sources}/tutorial.rst +151 -1
- {alembic-1.16.0 → alembic-1.16.2}/docs/_static/documentation_options.js +1 -1
- {alembic-1.16.0 → alembic-1.16.2}/docs/api/autogenerate.html +3 -3
- {alembic-1.16.0 → alembic-1.16.2}/docs/api/commands.html +3 -3
- {alembic-1.16.0 → alembic-1.16.2}/docs/api/config.html +17 -4
- {alembic-1.16.0 → alembic-1.16.2}/docs/api/ddl.html +3 -3
- {alembic-1.16.0 → alembic-1.16.2}/docs/api/index.html +3 -3
- {alembic-1.16.0 → alembic-1.16.2}/docs/api/operations.html +3 -3
- {alembic-1.16.0 → alembic-1.16.2}/docs/api/overview.html +3 -3
- {alembic-1.16.0 → alembic-1.16.2}/docs/api/runtime.html +3 -3
- {alembic-1.16.0 → alembic-1.16.2}/docs/api/script.html +3 -3
- {alembic-1.16.0 → alembic-1.16.2}/docs/autogenerate.html +3 -3
- {alembic-1.16.0 → alembic-1.16.2}/docs/batch.html +3 -3
- {alembic-1.16.0 → alembic-1.16.2}/docs/branches.html +3 -3
- {alembic-1.16.0 → alembic-1.16.2}/docs/build/changelog.rst +45 -0
- {alembic-1.16.0 → alembic-1.16.2}/docs/build/conf.py +2 -2
- {alembic-1.16.0/docs/_sources → alembic-1.16.2/docs/build}/tutorial.rst +151 -1
- {alembic-1.16.0 → alembic-1.16.2}/docs/changelog.html +63 -3
- {alembic-1.16.0 → alembic-1.16.2}/docs/cookbook.html +3 -3
- {alembic-1.16.0 → alembic-1.16.2}/docs/front.html +3 -3
- {alembic-1.16.0 → alembic-1.16.2}/docs/genindex.html +7 -5
- {alembic-1.16.0 → alembic-1.16.2}/docs/index.html +15 -4
- {alembic-1.16.0 → alembic-1.16.2}/docs/naming.html +3 -3
- {alembic-1.16.0 → alembic-1.16.2}/docs/offline.html +3 -3
- {alembic-1.16.0 → alembic-1.16.2}/docs/ops.html +3 -3
- {alembic-1.16.0 → alembic-1.16.2}/docs/py-modindex.html +3 -3
- {alembic-1.16.0 → alembic-1.16.2}/docs/search.html +3 -3
- alembic-1.16.2/docs/searchindex.js +1 -0
- {alembic-1.16.0 → alembic-1.16.2}/docs/tutorial.html +159 -6
- {alembic-1.16.0 → alembic-1.16.2}/tests/test_autogen_render.py +18 -0
- {alembic-1.16.0 → alembic-1.16.2}/tests/test_command.py +105 -1
- {alembic-1.16.0 → alembic-1.16.2}/tests/test_postgresql.py +10 -0
- {alembic-1.16.0 → alembic-1.16.2}/tox.ini +2 -2
- alembic-1.16.0/docs/searchindex.js +0 -1
- {alembic-1.16.0 → alembic-1.16.2}/CHANGES +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/LICENSE +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/MANIFEST.in +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/README.rst +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/README.unittests.rst +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/alembic/__main__.py +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/alembic/autogenerate/__init__.py +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/alembic/autogenerate/api.py +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/alembic/context.py +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/alembic/context.pyi +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/alembic/ddl/__init__.py +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/alembic/ddl/_autogen.py +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/alembic/ddl/base.py +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/alembic/ddl/impl.py +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/alembic/ddl/mssql.py +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/alembic/ddl/mysql.py +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/alembic/ddl/oracle.py +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/alembic/ddl/postgresql.py +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/alembic/ddl/sqlite.py +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/alembic/environment.py +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/alembic/migration.py +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/alembic/op.py +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/alembic/op.pyi +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/alembic/operations/__init__.py +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/alembic/operations/base.py +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/alembic/operations/batch.py +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/alembic/operations/ops.py +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/alembic/operations/schemaobj.py +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/alembic/operations/toimpl.py +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/alembic/py.typed +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/alembic/runtime/__init__.py +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/alembic/script/__init__.py +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/alembic/script/revision.py +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/alembic/script/write_hooks.py +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/alembic/templates/async/README +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/alembic/templates/async/alembic.ini.mako +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/alembic/templates/async/env.py +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/alembic/templates/generic/README +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/alembic/templates/generic/alembic.ini.mako +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/alembic/templates/generic/env.py +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/alembic/templates/multidb/README +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/alembic/templates/multidb/alembic.ini.mako +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/alembic/templates/multidb/env.py +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/alembic/templates/pyproject/README +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/alembic/templates/pyproject/alembic.ini.mako +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/alembic/templates/pyproject/env.py +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/alembic/templates/pyproject/pyproject.toml.mako +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/alembic/testing/__init__.py +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/alembic/testing/assertions.py +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/alembic/testing/env.py +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/alembic/testing/fixtures.py +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/alembic/testing/plugin/__init__.py +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/alembic/testing/plugin/bootstrap.py +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/alembic/testing/requirements.py +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/alembic/testing/schemacompare.py +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/alembic/testing/suite/__init__.py +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/alembic/testing/suite/_autogen_fixtures.py +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/alembic/testing/suite/test_autogen_comments.py +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/alembic/testing/suite/test_autogen_computed.py +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/alembic/testing/suite/test_autogen_diffs.py +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/alembic/testing/suite/test_autogen_fks.py +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/alembic/testing/suite/test_autogen_identity.py +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/alembic/testing/suite/test_environment.py +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/alembic/testing/suite/test_op.py +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/alembic/testing/util.py +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/alembic/testing/warnings.py +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/alembic/util/__init__.py +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/alembic/util/compat.py +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/alembic/util/editor.py +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/alembic/util/exc.py +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/alembic/util/langhelpers.py +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/alembic/util/messaging.py +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/alembic/util/sqla_compat.py +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/alembic.egg-info/SOURCES.txt +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/alembic.egg-info/dependency_links.txt +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/alembic.egg-info/entry_points.txt +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/alembic.egg-info/not-zip-safe +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/alembic.egg-info/requires.txt +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/alembic.egg-info/top_level.txt +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/docs/_images/api_overview.png +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/docs/_sources/api/autogenerate.rst +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/docs/_sources/api/commands.rst +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/docs/_sources/api/config.rst +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/docs/_sources/api/ddl.rst +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/docs/_sources/api/index.rst +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/docs/_sources/api/operations.rst +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/docs/_sources/api/overview.rst +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/docs/_sources/api/runtime.rst +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/docs/_sources/api/script.rst +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/docs/_sources/autogenerate.rst +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/docs/_sources/batch.rst +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/docs/_sources/branches.rst +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/docs/_sources/cookbook.rst +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/docs/_sources/front.rst +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/docs/_sources/index.rst +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/docs/_sources/naming.rst +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/docs/_sources/offline.rst +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/docs/_sources/ops.rst +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/docs/_static/basic.css +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/docs/_static/changelog.css +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/docs/_static/clipboard.min.js +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/docs/_static/copybutton.css +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/docs/_static/copybutton.js +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/docs/_static/copybutton_funcs.js +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/docs/_static/doctools.js +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/docs/_static/file.png +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/docs/_static/images/logo_colab.png +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/docs/_static/language_data.js +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/docs/_static/minus.png +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/docs/_static/nature_override.css +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/docs/_static/plus.png +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/docs/_static/pygments.css +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/docs/_static/sbt-webpack-macros.html +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/docs/_static/scripts/bootstrap.js +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/docs/_static/scripts/bootstrap.js.LICENSE.txt +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/docs/_static/scripts/pydata-sphinx-theme.js +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/docs/_static/scripts/sphinx-book-theme.js +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/docs/_static/searchtools.js +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/docs/_static/site_custom_css.css +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/docs/_static/sphinx_highlight.js +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/docs/_static/sphinx_paramlinks.css +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/docs/_static/styles/bootstrap.css +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/docs/_static/styles/pydata-sphinx-theme.css +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/docs/_static/styles/sphinx-book-theme.css +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/docs/_static/styles/theme.css +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/docs/_static/vendor/fontawesome/6.5.2/LICENSE.txt +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/docs/_static/vendor/fontawesome/6.5.2/css/all.min.css +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/docs/_static/vendor/fontawesome/6.5.2/js/all.min.js +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/docs/_static/vendor/fontawesome/6.5.2/js/all.min.js.LICENSE.txt +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/docs/_static/webpack-macros.html +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/docs/build/Makefile +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/docs/build/_static/nature_override.css +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/docs/build/_static/site_custom_css.css +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/docs/build/_templates/site_custom_sidebars.html +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/docs/build/api/api_overview.png +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/docs/build/api/autogenerate.rst +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/docs/build/api/commands.rst +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/docs/build/api/config.rst +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/docs/build/api/ddl.rst +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/docs/build/api/index.rst +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/docs/build/api/operations.rst +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/docs/build/api/overview.rst +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/docs/build/api/runtime.rst +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/docs/build/api/script.rst +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/docs/build/autogenerate.rst +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/docs/build/batch.rst +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/docs/build/branches.rst +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/docs/build/cookbook.rst +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/docs/build/front.rst +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/docs/build/index.rst +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/docs/build/naming.rst +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/docs/build/offline.rst +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/docs/build/ops.rst +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/docs/build/requirements.txt +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/docs/build/unreleased/README.txt +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/pyproject.toml +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/setup.cfg +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/setup.py +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/tests/__init__.py +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/tests/_large_map.py +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/tests/conftest.py +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/tests/requirements.py +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/tests/test_autogen_composition.py +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/tests/test_autogen_diffs.py +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/tests/test_autogen_indexes.py +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/tests/test_batch.py +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/tests/test_bulk_insert.py +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/tests/test_config.py +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/tests/test_editor.py +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/tests/test_environment.py +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/tests/test_external_dialect.py +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/tests/test_impl.py +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/tests/test_messaging.py +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/tests/test_mssql.py +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/tests/test_mysql.py +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/tests/test_offline_environment.py +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/tests/test_op.py +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/tests/test_op_naming_convention.py +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/tests/test_oracle.py +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/tests/test_post_write.py +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/tests/test_revision.py +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/tests/test_script_consumption.py +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/tests/test_script_production.py +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/tests/test_sqlite.py +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/tests/test_stubs.py +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/tests/test_suite.py +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/tests/test_version_table.py +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/tests/test_version_traversal.py +0 -0
- {alembic-1.16.0 → alembic-1.16.2}/tools/write_pyi.py +0 -0
@@ -683,7 +683,7 @@ def _compare_indexes_and_uniques(
|
|
683
683
|
):
|
684
684
|
modify_ops.ops.append(ops.CreateIndexOp.from_index(obj.const))
|
685
685
|
log.info(
|
686
|
-
"Detected added index
|
686
|
+
"Detected added index %r on '%s'",
|
687
687
|
obj.name,
|
688
688
|
obj.column_names,
|
689
689
|
)
|
@@ -1282,7 +1282,7 @@ def _compare_foreign_keys(
|
|
1282
1282
|
obj.const, obj.name, "foreign_key_constraint", False, compare_to
|
1283
1283
|
):
|
1284
1284
|
modify_table_ops.ops.append(
|
1285
|
-
ops.CreateForeignKeyOp.from_constraint(const.const)
|
1285
|
+
ops.CreateForeignKeyOp.from_constraint(const.const)
|
1286
1286
|
)
|
1287
1287
|
|
1288
1288
|
log.info(
|
@@ -18,6 +18,7 @@ from mako.pygen import PythonPrinter
|
|
18
18
|
from sqlalchemy import schema as sa_schema
|
19
19
|
from sqlalchemy import sql
|
20
20
|
from sqlalchemy import types as sqltypes
|
21
|
+
from sqlalchemy.sql.base import _DialectArgView
|
21
22
|
from sqlalchemy.sql.elements import conv
|
22
23
|
from sqlalchemy.sql.elements import Label
|
23
24
|
from sqlalchemy.sql.elements import quoted_name
|
@@ -31,7 +32,6 @@ if TYPE_CHECKING:
|
|
31
32
|
|
32
33
|
from sqlalchemy import Computed
|
33
34
|
from sqlalchemy import Identity
|
34
|
-
from sqlalchemy.sql.base import DialectKWArgs
|
35
35
|
from sqlalchemy.sql.elements import ColumnElement
|
36
36
|
from sqlalchemy.sql.elements import TextClause
|
37
37
|
from sqlalchemy.sql.schema import CheckConstraint
|
@@ -304,11 +304,11 @@ def _drop_table(autogen_context: AutogenContext, op: ops.DropTableOp) -> str:
|
|
304
304
|
|
305
305
|
|
306
306
|
def _render_dialect_kwargs_items(
|
307
|
-
autogen_context: AutogenContext,
|
307
|
+
autogen_context: AutogenContext, dialect_kwargs: _DialectArgView
|
308
308
|
) -> list[str]:
|
309
309
|
return [
|
310
310
|
f"{key}={_render_potential_expr(val, autogen_context)}"
|
311
|
-
for key, val in
|
311
|
+
for key, val in dialect_kwargs.items()
|
312
312
|
]
|
313
313
|
|
314
314
|
|
@@ -331,7 +331,7 @@ def _add_index(autogen_context: AutogenContext, op: ops.CreateIndexOp) -> str:
|
|
331
331
|
|
332
332
|
assert index.table is not None
|
333
333
|
|
334
|
-
opts = _render_dialect_kwargs_items(autogen_context, index)
|
334
|
+
opts = _render_dialect_kwargs_items(autogen_context, index.dialect_kwargs)
|
335
335
|
if op.if_not_exists is not None:
|
336
336
|
opts.append("if_not_exists=%r" % bool(op.if_not_exists))
|
337
337
|
text = tmpl % {
|
@@ -365,7 +365,7 @@ def _drop_index(autogen_context: AutogenContext, op: ops.DropIndexOp) -> str:
|
|
365
365
|
"%(prefix)sdrop_index(%(name)r, "
|
366
366
|
"table_name=%(table_name)r%(schema)s%(kwargs)s)"
|
367
367
|
)
|
368
|
-
opts = _render_dialect_kwargs_items(autogen_context, index)
|
368
|
+
opts = _render_dialect_kwargs_items(autogen_context, index.dialect_kwargs)
|
369
369
|
if op.if_exists is not None:
|
370
370
|
opts.append("if_exists=%r" % bool(op.if_exists))
|
371
371
|
text = tmpl % {
|
@@ -389,6 +389,7 @@ def _add_unique_constraint(
|
|
389
389
|
def _add_fk_constraint(
|
390
390
|
autogen_context: AutogenContext, op: ops.CreateForeignKeyOp
|
391
391
|
) -> str:
|
392
|
+
constraint = op.to_constraint()
|
392
393
|
args = [repr(_render_gen_name(autogen_context, op.constraint_name))]
|
393
394
|
if not autogen_context._has_batch:
|
394
395
|
args.append(repr(_ident(op.source_table)))
|
@@ -418,9 +419,16 @@ def _add_fk_constraint(
|
|
418
419
|
if value is not None:
|
419
420
|
args.append("%s=%r" % (k, value))
|
420
421
|
|
421
|
-
|
422
|
+
dialect_kwargs = _render_dialect_kwargs_items(
|
423
|
+
autogen_context, constraint.dialect_kwargs
|
424
|
+
)
|
425
|
+
|
426
|
+
return "%(prefix)screate_foreign_key(%(args)s%(dialect_kwargs)s)" % {
|
422
427
|
"prefix": _alembic_autogenerate_prefix(autogen_context),
|
423
428
|
"args": ", ".join(args),
|
429
|
+
"dialect_kwargs": (
|
430
|
+
", " + ", ".join(dialect_kwargs) if dialect_kwargs else ""
|
431
|
+
),
|
424
432
|
}
|
425
433
|
|
426
434
|
|
@@ -664,7 +672,9 @@ def _uq_constraint(
|
|
664
672
|
opts.append(
|
665
673
|
("name", _render_gen_name(autogen_context, constraint.name))
|
666
674
|
)
|
667
|
-
dialect_options = _render_dialect_kwargs_items(
|
675
|
+
dialect_options = _render_dialect_kwargs_items(
|
676
|
+
autogen_context, constraint.dialect_kwargs
|
677
|
+
)
|
668
678
|
|
669
679
|
if alter:
|
670
680
|
args = [repr(_render_gen_name(autogen_context, constraint.name))]
|
@@ -177,7 +177,7 @@ class Rewriter:
|
|
177
177
|
)
|
178
178
|
upgrade_ops_list.append(ret[0])
|
179
179
|
|
180
|
-
directive.upgrade_ops = upgrade_ops_list
|
180
|
+
directive.upgrade_ops = upgrade_ops_list
|
181
181
|
|
182
182
|
downgrade_ops_list: List[DowngradeOps] = []
|
183
183
|
for downgrade_ops in directive.downgrade_ops_list:
|
@@ -187,7 +187,7 @@ class Rewriter:
|
|
187
187
|
"Can only return single object for DowngradeOps traverse"
|
188
188
|
)
|
189
189
|
downgrade_ops_list.append(ret[0])
|
190
|
-
directive.downgrade_ops = downgrade_ops_list
|
190
|
+
directive.downgrade_ops = downgrade_ops_list
|
191
191
|
|
192
192
|
@_traverse.dispatch_for(ops.OpContainer)
|
193
193
|
def _traverse_op_container(
|
@@ -68,7 +68,7 @@ def init(
|
|
68
68
|
template_path = config._get_template_path() / template
|
69
69
|
|
70
70
|
if not template_path.exists():
|
71
|
-
raise util.CommandError("No such template {template_path}")
|
71
|
+
raise util.CommandError(f"No such template {template_path}")
|
72
72
|
|
73
73
|
# left as os.access() to suit unit test mocking
|
74
74
|
if not os.access(directory_path, os.F_OK):
|
@@ -75,7 +75,20 @@ class Config:
|
|
75
75
|
alembic_cfg.attributes['connection'] = connection
|
76
76
|
command.upgrade(alembic_cfg, "head")
|
77
77
|
|
78
|
-
:param file\_: name of the .ini file to open.
|
78
|
+
:param file\_: name of the .ini file to open if an ``alembic.ini`` is
|
79
|
+
to be used. This should refer to the ``alembic.ini`` file, either as
|
80
|
+
a filename or a full path to the file. This filename if passed must refer
|
81
|
+
to an **ini file in ConfigParser format** only.
|
82
|
+
|
83
|
+
:param toml\_file: name of the pyproject.toml file to open if a
|
84
|
+
``pyproject.toml`` file is to be used. This should refer to the
|
85
|
+
``pyproject.toml`` file, either as a filename or a full path to the file.
|
86
|
+
This file must be in toml format. Both :paramref:`.Config.file\_` and
|
87
|
+
:paramref:`.Config.toml\_file` may be passed simultaneously, or
|
88
|
+
exclusively.
|
89
|
+
|
90
|
+
.. versionadded:: 1.16.0
|
91
|
+
|
79
92
|
:param ini_section: name of the main Alembic section within the
|
80
93
|
.ini file
|
81
94
|
:param output_buffer: optional file-like input buffer which
|
@@ -264,7 +277,10 @@ class Config:
|
|
264
277
|
commands.
|
265
278
|
|
266
279
|
"""
|
267
|
-
|
280
|
+
import alembic
|
281
|
+
|
282
|
+
package_dir = Path(alembic.__file__).absolute().parent
|
283
|
+
return str(package_dir / "templates")
|
268
284
|
|
269
285
|
def _get_template_path(self) -> Path:
|
270
286
|
"""Return the directory where Alembic setup templates are found.
|
@@ -275,10 +291,7 @@ class Config:
|
|
275
291
|
.. versionadded:: 1.16.0
|
276
292
|
|
277
293
|
"""
|
278
|
-
|
279
|
-
|
280
|
-
package_dir = Path(alembic.__file__).absolute().parent
|
281
|
-
return package_dir / "templates"
|
294
|
+
return Path(self.get_template_directory())
|
282
295
|
|
283
296
|
@overload
|
284
297
|
def get_section(
|
@@ -338,7 +338,7 @@ class EnvironmentContext(util.ModuleClsProxy):
|
|
338
338
|
line.
|
339
339
|
|
340
340
|
"""
|
341
|
-
return self.context_opts.get("tag", None)
|
341
|
+
return self.context_opts.get("tag", None)
|
342
342
|
|
343
343
|
@overload
|
344
344
|
def get_x_argument(self, as_dictionary: Literal[False]) -> List[str]: ...
|
@@ -175,7 +175,11 @@ class MigrationContext:
|
|
175
175
|
opts["output_encoding"],
|
176
176
|
)
|
177
177
|
else:
|
178
|
-
self.output_buffer = opts.get(
|
178
|
+
self.output_buffer = opts.get(
|
179
|
+
"output_buffer", sys.stdout
|
180
|
+
) # type:ignore[assignment] # noqa: E501
|
181
|
+
|
182
|
+
self.transactional_ddl = transactional_ddl
|
179
183
|
|
180
184
|
self._user_compare_type = opts.get("compare_type", True)
|
181
185
|
self._user_compare_server_default = opts.get(
|
@@ -560,7 +560,11 @@ class ScriptDirectory:
|
|
560
560
|
**self.messaging_opts,
|
561
561
|
):
|
562
562
|
util.template_to_file(
|
563
|
-
src,
|
563
|
+
src,
|
564
|
+
dest,
|
565
|
+
self.output_encoding,
|
566
|
+
append_with_newlines=True,
|
567
|
+
**kw,
|
564
568
|
)
|
565
569
|
|
566
570
|
def _generate_template(self, src: Path, dest: Path, **kw: Any) -> None:
|
@@ -846,7 +850,7 @@ class Script(revision.Revision):
|
|
846
850
|
doc = doc.decode( # type: ignore[attr-defined]
|
847
851
|
self.module._alembic_source_encoding
|
848
852
|
)
|
849
|
-
return doc.strip()
|
853
|
+
return doc.strip()
|
850
854
|
else:
|
851
855
|
return ""
|
852
856
|
|
@@ -13,7 +13,7 @@ ${imports if imports else ""}
|
|
13
13
|
|
14
14
|
# revision identifiers, used by Alembic.
|
15
15
|
revision: str = ${repr(up_revision)}
|
16
|
-
down_revision: Union[str, None] = ${repr(down_revision)}
|
16
|
+
down_revision: Union[str, Sequence[str], None] = ${repr(down_revision)}
|
17
17
|
branch_labels: Union[str, Sequence[str], None] = ${repr(branch_labels)}
|
18
18
|
depends_on: Union[str, Sequence[str], None] = ${repr(depends_on)}
|
19
19
|
|
@@ -13,7 +13,7 @@ ${imports if imports else ""}
|
|
13
13
|
|
14
14
|
# revision identifiers, used by Alembic.
|
15
15
|
revision: str = ${repr(up_revision)}
|
16
|
-
down_revision: Union[str, None] = ${repr(down_revision)}
|
16
|
+
down_revision: Union[str, Sequence[str], None] = ${repr(down_revision)}
|
17
17
|
branch_labels: Union[str, Sequence[str], None] = ${repr(branch_labels)}
|
18
18
|
depends_on: Union[str, Sequence[str], None] = ${repr(depends_on)}
|
19
19
|
|
@@ -16,7 +16,7 @@ ${imports if imports else ""}
|
|
16
16
|
|
17
17
|
# revision identifiers, used by Alembic.
|
18
18
|
revision: str = ${repr(up_revision)}
|
19
|
-
down_revision: Union[str, None] = ${repr(down_revision)}
|
19
|
+
down_revision: Union[str, Sequence[str], None] = ${repr(down_revision)}
|
20
20
|
branch_labels: Union[str, Sequence[str], None] = ${repr(branch_labels)}
|
21
21
|
depends_on: Union[str, Sequence[str], None] = ${repr(depends_on)}
|
22
22
|
|
@@ -13,7 +13,7 @@ ${imports if imports else ""}
|
|
13
13
|
|
14
14
|
# revision identifiers, used by Alembic.
|
15
15
|
revision: str = ${repr(up_revision)}
|
16
|
-
down_revision: Union[str, None] = ${repr(down_revision)}
|
16
|
+
down_revision: Union[str, Sequence[str], None] = ${repr(down_revision)}
|
17
17
|
branch_labels: Union[str, Sequence[str], None] = ${repr(branch_labels)}
|
18
18
|
depends_on: Union[str, Sequence[str], None] = ${repr(depends_on)}
|
19
19
|
|
@@ -26,7 +26,7 @@ def template_to_file(
|
|
26
26
|
dest: Union[str, os.PathLike[str]],
|
27
27
|
output_encoding: str,
|
28
28
|
*,
|
29
|
-
|
29
|
+
append_with_newlines: bool = False,
|
30
30
|
**kw: Any,
|
31
31
|
) -> None:
|
32
32
|
template = Template(filename=_preserving_path_as_str(template_file))
|
@@ -45,7 +45,9 @@ def template_to_file(
|
|
45
45
|
"template-oriented traceback." % fname
|
46
46
|
)
|
47
47
|
else:
|
48
|
-
with open(dest, "ab" if
|
48
|
+
with open(dest, "ab" if append_with_newlines else "wb") as f:
|
49
|
+
if append_with_newlines:
|
50
|
+
f.write("\n\n".encode(output_encoding))
|
49
51
|
f.write(output)
|
50
52
|
|
51
53
|
|
@@ -3,6 +3,51 @@
|
|
3
3
|
Changelog
|
4
4
|
==========
|
5
5
|
|
6
|
+
.. changelog::
|
7
|
+
:version: 1.16.2
|
8
|
+
:released: June 16, 2025
|
9
|
+
|
10
|
+
.. change::
|
11
|
+
:tags: bug, autogenerate
|
12
|
+
:tickets: 1671
|
13
|
+
|
14
|
+
Fixed issue where dialect-specific keyword arguments in ``dialect_kwargs``
|
15
|
+
were not rendered when rendering the :meth:`.Operations.create_foreign_key`
|
16
|
+
operation. This prevented dialect-specific keywords from being rendered
|
17
|
+
using custom :class:`.Rewriter` recipes that modify
|
18
|
+
:class:`.ops.CreateForeignKeyOp`, similar to other issues such as
|
19
|
+
:ticket:`1635`. Pull request courtesy Justin Malin.
|
20
|
+
|
21
|
+
.. change::
|
22
|
+
:tags: bug, command
|
23
|
+
:tickets: 1679
|
24
|
+
|
25
|
+
Fixed rendering of ``pyproject.toml`` to include two newlines when
|
26
|
+
appending content to an existing file. Pull request courtesy Jonathan
|
27
|
+
Vanasco.
|
28
|
+
|
29
|
+
|
30
|
+
.. changelog::
|
31
|
+
:version: 1.16.1
|
32
|
+
:released: May 21, 2025
|
33
|
+
|
34
|
+
.. change::
|
35
|
+
:tags: bug, command
|
36
|
+
:tickets: 1660
|
37
|
+
|
38
|
+
Fixed regression caused by the ``pathlib`` refactoring that removed the use
|
39
|
+
of :meth:`.Config.get_template_directory` as the canonical source of
|
40
|
+
templates; the method is still present however it no longer would be
|
41
|
+
consulted for a custom config subclass, as was the case with flask-migrate.
|
42
|
+
|
43
|
+
.. change::
|
44
|
+
:tags: bug, command
|
45
|
+
:tickets: 1659
|
46
|
+
|
47
|
+
Fixed regression caused by the ``pathlib`` refactoring where the "missing
|
48
|
+
template" error message failed to render the name of the template that
|
49
|
+
could not be found.
|
50
|
+
|
6
51
|
.. changelog::
|
7
52
|
:version: 1.16.0
|
8
53
|
:released: May 21, 2025
|
@@ -141,7 +141,7 @@ indicate an alternative location, the ``--config`` option may be used, or the
|
|
141
141
|
The file generated with the ``generic`` configuration template contains all directives
|
142
142
|
for both source code configuration as well as database configuration. When using
|
143
143
|
the ``pyproject`` template, the source code configuration elements will instead
|
144
|
-
be in a separate ``pyproject.toml`` file, described in the :ref:`
|
144
|
+
be in a separate ``pyproject.toml`` file, described in the section :ref:`using_pep_621`.
|
145
145
|
|
146
146
|
The all-in-one .ini file created by ``generic`` is illustrated below::
|
147
147
|
|
@@ -232,6 +232,8 @@ The all-in-one .ini file created by ``generic`` is illustrated below::
|
|
232
232
|
# database URL. This is consumed by the user-maintained env.py script only.
|
233
233
|
# other means of configuring database URLs may be customized within the env.py
|
234
234
|
# file.
|
235
|
+
# See notes in "escaping characters in ini files" for guidelines on
|
236
|
+
# passwords
|
235
237
|
sqlalchemy.url = driver://user:pass@localhost/dbname
|
236
238
|
|
237
239
|
# [post_write_hooks]
|
@@ -295,6 +297,13 @@ provided as a substitution which is populated with the absolute path to the
|
|
295
297
|
``alembic.ini`` file itself. This can be used to produce correct pathnames
|
296
298
|
to directories and files relative to where the config file is located.
|
297
299
|
|
300
|
+
.. tip:: Percent signs in ``alembic.ini`` configuration variables that are
|
301
|
+
not part of an interpolation token like ``%(here)s``, including percent
|
302
|
+
signs that are part of the SQLAlchemy database URL for its own URL-escaping
|
303
|
+
requirements, must themselves be escaped.
|
304
|
+
See the section :ref:`escaping_percent_signs` for more information.
|
305
|
+
|
306
|
+
|
298
307
|
This file contains the following features:
|
299
308
|
|
300
309
|
* ``[alembic]`` - this is the section read by Alembic to determine configuration. Alembic's
|
@@ -416,6 +425,141 @@ the SQLAlchemy URL is all that's needed::
|
|
416
425
|
|
417
426
|
sqlalchemy.url = postgresql://scott:tiger@localhost/test
|
418
427
|
|
428
|
+
.. _escaping_percent_signs:
|
429
|
+
|
430
|
+
Escaping Characters in ini files
|
431
|
+
--------------------------------
|
432
|
+
|
433
|
+
As mentioned previously, Alembic's .ini file format uses Python `ConfigParser
|
434
|
+
<https://docs.python.org/3/library/configparser.html#configparser.ConfigParser>`_
|
435
|
+
to parse the file. ``ConfigParser`` 's `interpolation feature is enabled
|
436
|
+
<https://docs.python.org/3/library/configparser.html#interpolation-of-values>`_
|
437
|
+
in this operation to support the use of the ``%(here)s`` token, as well as any
|
438
|
+
other tokens that are user-configurable via the :paramref:`.Config.config_args`
|
439
|
+
parameter when creating a custom :class:`.Config` object.
|
440
|
+
|
441
|
+
This means that any literal string that includes a percent sign that is not
|
442
|
+
part of an interpolated variable must be escaped by doubling it. That is, for
|
443
|
+
a configuration value like this in a Python script::
|
444
|
+
|
445
|
+
my_configuration_value = "some % string"
|
446
|
+
|
447
|
+
To be parsed from the .ini file would need to be placed as::
|
448
|
+
|
449
|
+
[alembic]
|
450
|
+
|
451
|
+
my_configuration_value = some %% string
|
452
|
+
|
453
|
+
This escaping can be seen in the sample ``alembic.ini`` file, illustrated in
|
454
|
+
such values as ``file_template``::
|
455
|
+
|
456
|
+
# template used to generate migration file names; The default value is %%(rev)s_%%(slug)s
|
457
|
+
file_template = %%(year)d_%%(month).2d_%%(day).2d_%%(hour).2d%%(minute).2d-%%(rev)s_%%(slug)s
|
458
|
+
|
459
|
+
Where above, the actual ``file_template`` that is sent to Alembic's file generation system
|
460
|
+
would be ``%(year)d_%(month).2d_%(day).2d_%(hour).2d%(minute).2d-%(rev)s_%(slug)s``.
|
461
|
+
|
462
|
+
.. tip:: Alembic also employs percent-sign interpolation of values when retrieving
|
463
|
+
values from a ``pyproject.toml`` file, as documented at :ref:`using_pep_621`.
|
464
|
+
So the same percent-doubling steps must be applied in Alembic-parsed values,
|
465
|
+
for fields such as ``file_template``.
|
466
|
+
|
467
|
+
For the SQLAlchemy URL, percent signs are used to escape syntactically-
|
468
|
+
significant characters such as the ``@`` sign as well as the percent sign
|
469
|
+
itself. For a password such as ``"P@ssw%rd"``::
|
470
|
+
|
471
|
+
>>> my_actual_password = "P@ssw%rd"
|
472
|
+
|
473
|
+
As `documented by SQLAlchemy <https://docs.sqlalchemy.org/core/engines.html#escaping-special-characters-such-as-signs-in-passwords>`_,
|
474
|
+
the ``@`` sign as well as the percent sign when placed into a URL should be escaped with ``urllib.parse.quote_plus``::
|
475
|
+
|
476
|
+
>>> import urllib.parse
|
477
|
+
>>> sqlalchemy_quoted_password = urllib.parse.quote_plus(my_actual_password)
|
478
|
+
>>> sqlalchemy_quoted_password
|
479
|
+
'P%40ssw%25rd'
|
480
|
+
|
481
|
+
This URL quoting can also be seen in SQLAlchemy's own stringification of
|
482
|
+
URLs::
|
483
|
+
|
484
|
+
>>> from sqlalchemy import URL
|
485
|
+
>>> URL.create(
|
486
|
+
... "some_db", username="scott", password=my_actual_password, host="host"
|
487
|
+
... ).render_as_string(hide_password=False)
|
488
|
+
'some_db://scott:P%40ssw%25rd@host'
|
489
|
+
|
490
|
+
For the above escaped password string ``'P%40ssw%rd'`` to be placed into a ``ConfigParser`` file that
|
491
|
+
includes interpolation of percent signs, ``%`` characters are doubled::
|
492
|
+
|
493
|
+
>>> sqlalchemy_quoted_password.replace("%", "%%")
|
494
|
+
'P%%40ssw%%25rd'
|
495
|
+
|
496
|
+
Here's a complete program that will compose a URL and show the correct configparser form
|
497
|
+
for a given set of database connection details, as well as illustrate how to assert these
|
498
|
+
forms for correctness::
|
499
|
+
|
500
|
+
from sqlalchemy import URL, make_url
|
501
|
+
|
502
|
+
database_driver = input("database driver? ")
|
503
|
+
username = input("username? ")
|
504
|
+
password = input("password? ")
|
505
|
+
host = input("host? ")
|
506
|
+
port = input("port? ")
|
507
|
+
database = input("database? ")
|
508
|
+
|
509
|
+
sqlalchemy_url = URL.create(
|
510
|
+
drivername=database_driver,
|
511
|
+
username=username,
|
512
|
+
password=password,
|
513
|
+
host=host,
|
514
|
+
port=int(port),
|
515
|
+
database=database,
|
516
|
+
)
|
517
|
+
|
518
|
+
stringified_sqlalchemy_url = sqlalchemy_url.render_as_string(
|
519
|
+
hide_password=False
|
520
|
+
)
|
521
|
+
|
522
|
+
# assert make_url round trip
|
523
|
+
assert make_url(stringified_sqlalchemy_url) == sqlalchemy_url
|
524
|
+
|
525
|
+
print(
|
526
|
+
f"The correctly escaped string that can be passed "
|
527
|
+
f"to SQLAlchemy make_url() and create_engine() is:"
|
528
|
+
f"\n\n {stringified_sqlalchemy_url!r}\n"
|
529
|
+
)
|
530
|
+
|
531
|
+
percent_replaced_url = stringified_sqlalchemy_url.replace("%", "%%")
|
532
|
+
|
533
|
+
# assert percent-interpolated plus make_url round trip
|
534
|
+
assert make_url(percent_replaced_url % {}) == sqlalchemy_url
|
535
|
+
|
536
|
+
print(
|
537
|
+
f"The SQLAlchemy URL that can be placed in a ConfigParser "
|
538
|
+
f"file such as alembic.ini is:\n\n "
|
539
|
+
f"sqlalchemy.url = {percent_replaced_url}\n"
|
540
|
+
)
|
541
|
+
|
542
|
+
The above program should eliminate any ambiguity when placing a SQLAlchemy
|
543
|
+
URL into a configparser file::
|
544
|
+
|
545
|
+
$ python alembic_pw_script.py
|
546
|
+
database driver? postgresql+psycopg2
|
547
|
+
username? scott
|
548
|
+
password? P@ssw%rd
|
549
|
+
host? localhost
|
550
|
+
port? 5432
|
551
|
+
database? testdb
|
552
|
+
The correctly escaped string that can be passed to SQLAlchemy make_url() and create_engine() is:
|
553
|
+
|
554
|
+
'postgresql+psycopg2://scott:P%40ssw%25rd@localhost:5432/testdb'
|
555
|
+
|
556
|
+
The SQLAlchemy URL that can be placed in a ConfigParser file such as alembic.ini is:
|
557
|
+
|
558
|
+
sqlalchemy.url = postgresql+psycopg2://scott:P%%40ssw%%25rd@localhost:5432/testdb
|
559
|
+
|
560
|
+
|
561
|
+
|
562
|
+
|
419
563
|
.. _using_pep_621:
|
420
564
|
|
421
565
|
Using pyproject.toml for configuration
|
@@ -539,6 +683,12 @@ remains available as the absolute path to the ``pyproject.toml`` file::
|
|
539
683
|
# executable = "%(here)s/.venv/bin/ruff"
|
540
684
|
# options = "check --fix REVISION_SCRIPT_FILENAME"
|
541
685
|
|
686
|
+
.. tip:: As Alembic adds support for interpolation tokens like ``%(here)s`` to
|
687
|
+
its handling of ``pyproject.toml`` values, the same percent-sign escaping
|
688
|
+
steps that apply to ``alembic.ini`` configuration variables also apply
|
689
|
+
to ``pyproject.toml``, even though database URLs are not configured in this
|
690
|
+
file. This escaping can be seen in the sample ``file_template`` value
|
691
|
+
above. See the section :ref:`escaping_percent_signs` for background.
|
542
692
|
|
543
693
|
The ``alembic.ini`` file for this template is truncated and contains
|
544
694
|
only database configuration and logging configuration::
|
@@ -8,7 +8,7 @@
|
|
8
8
|
<meta charset="utf-8" />
|
9
9
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="viewport" content="width=device-width, initial-scale=1" />
|
10
10
|
|
11
|
-
<title>Autogeneration — Alembic 1.16.
|
11
|
+
<title>Autogeneration — Alembic 1.16.2 documentation</title>
|
12
12
|
|
13
13
|
|
14
14
|
|
@@ -40,7 +40,7 @@
|
|
40
40
|
<link rel="preload" as="script" href="../_static/scripts/pydata-sphinx-theme.js?digest=dfe6caa3a7d634c4db9b" />
|
41
41
|
<script src="../_static/vendor/fontawesome/6.5.2/js/all.min.js?digest=dfe6caa3a7d634c4db9b"></script>
|
42
42
|
|
43
|
-
<script src="../_static/documentation_options.js?v=
|
43
|
+
<script src="../_static/documentation_options.js?v=642e35fd"></script>
|
44
44
|
<script src="../_static/doctools.js?v=9bcbadda"></script>
|
45
45
|
<script src="../_static/sphinx_highlight.js?v=dc90522c"></script>
|
46
46
|
<script src="../_static/clipboard.min.js?v=a7894cd8"></script>
|
@@ -138,7 +138,7 @@
|
|
138
138
|
|
139
139
|
|
140
140
|
|
141
|
-
<p class="title logo__title">Alembic 1.16.
|
141
|
+
<p class="title logo__title">Alembic 1.16.2 documentation</p>
|
142
142
|
|
143
143
|
</a></div>
|
144
144
|
<div class="sidebar-primary-item"><ul class="navbar-icon-links"
|
@@ -8,7 +8,7 @@
|
|
8
8
|
<meta charset="utf-8" />
|
9
9
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="viewport" content="width=device-width, initial-scale=1" />
|
10
10
|
|
11
|
-
<title>Commands — Alembic 1.16.
|
11
|
+
<title>Commands — Alembic 1.16.2 documentation</title>
|
12
12
|
|
13
13
|
|
14
14
|
|
@@ -40,7 +40,7 @@
|
|
40
40
|
<link rel="preload" as="script" href="../_static/scripts/pydata-sphinx-theme.js?digest=dfe6caa3a7d634c4db9b" />
|
41
41
|
<script src="../_static/vendor/fontawesome/6.5.2/js/all.min.js?digest=dfe6caa3a7d634c4db9b"></script>
|
42
42
|
|
43
|
-
<script src="../_static/documentation_options.js?v=
|
43
|
+
<script src="../_static/documentation_options.js?v=642e35fd"></script>
|
44
44
|
<script src="../_static/doctools.js?v=9bcbadda"></script>
|
45
45
|
<script src="../_static/sphinx_highlight.js?v=dc90522c"></script>
|
46
46
|
<script src="../_static/clipboard.min.js?v=a7894cd8"></script>
|
@@ -138,7 +138,7 @@
|
|
138
138
|
|
139
139
|
|
140
140
|
|
141
|
-
<p class="title logo__title">Alembic 1.16.
|
141
|
+
<p class="title logo__title">Alembic 1.16.2 documentation</p>
|
142
142
|
|
143
143
|
</a></div>
|
144
144
|
<div class="sidebar-primary-item"><ul class="navbar-icon-links"
|
@@ -8,7 +8,7 @@
|
|
8
8
|
<meta charset="utf-8" />
|
9
9
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="viewport" content="width=device-width, initial-scale=1" />
|
10
10
|
|
11
|
-
<title>Configuration — Alembic 1.16.
|
11
|
+
<title>Configuration — Alembic 1.16.2 documentation</title>
|
12
12
|
|
13
13
|
|
14
14
|
|
@@ -40,7 +40,7 @@
|
|
40
40
|
<link rel="preload" as="script" href="../_static/scripts/pydata-sphinx-theme.js?digest=dfe6caa3a7d634c4db9b" />
|
41
41
|
<script src="../_static/vendor/fontawesome/6.5.2/js/all.min.js?digest=dfe6caa3a7d634c4db9b"></script>
|
42
42
|
|
43
|
-
<script src="../_static/documentation_options.js?v=
|
43
|
+
<script src="../_static/documentation_options.js?v=642e35fd"></script>
|
44
44
|
<script src="../_static/doctools.js?v=9bcbadda"></script>
|
45
45
|
<script src="../_static/sphinx_highlight.js?v=dc90522c"></script>
|
46
46
|
<script src="../_static/clipboard.min.js?v=a7894cd8"></script>
|
@@ -138,7 +138,7 @@
|
|
138
138
|
|
139
139
|
|
140
140
|
|
141
|
-
<p class="title logo__title">Alembic 1.16.
|
141
|
+
<p class="title logo__title">Alembic 1.16.2 documentation</p>
|
142
142
|
|
143
143
|
</a></div>
|
144
144
|
<div class="sidebar-primary-item"><ul class="navbar-icon-links"
|
@@ -504,7 +504,20 @@ engines, use the <a class="reference internal" href="#alembic.config.Config.attr
|
|
504
504
|
<dl class="field-list simple">
|
505
505
|
<dt class="field-odd">Parameters<span class="colon">:</span></dt>
|
506
506
|
<dd class="field-odd"><ul class="simple">
|
507
|
-
<li><p><span class="target" id="alembic.config.Config.params.file_"></span><strong>file_</strong><a class="paramlink headerlink reference internal" href="#alembic.config.Config.params.file_">¶</a> – name of the .ini file to open
|
507
|
+
<li><p><span class="target" id="alembic.config.Config.params.file_"></span><strong>file_</strong><a class="paramlink headerlink reference internal" href="#alembic.config.Config.params.file_">¶</a> – name of the .ini file to open if an <code class="docutils literal notranslate"><span class="pre">alembic.ini</span></code> is
|
508
|
+
to be used. This should refer to the <code class="docutils literal notranslate"><span class="pre">alembic.ini</span></code> file, either as
|
509
|
+
a filename or a full path to the file. This filename if passed must refer
|
510
|
+
to an <strong>ini file in ConfigParser format</strong> only.</p></li>
|
511
|
+
<li><p><span class="target" id="alembic.config.Config.params.toml_file"></span><strong>toml_file</strong><a class="paramlink headerlink reference internal" href="#alembic.config.Config.params.toml_file">¶</a> – <p>name of the pyproject.toml file to open if a
|
512
|
+
<code class="docutils literal notranslate"><span class="pre">pyproject.toml</span></code> file is to be used. This should refer to the
|
513
|
+
<code class="docutils literal notranslate"><span class="pre">pyproject.toml</span></code> file, either as a filename or a full path to the file.
|
514
|
+
This file must be in toml format. Both <a class="reference internal" href="#alembic.config.Config.params.file_" title="alembic.config.Config"><code class="xref py py-paramref docutils literal notranslate"><span class="pre">Config.file_</span></code></a> and
|
515
|
+
<a class="reference internal" href="#alembic.config.Config.params.toml_file" title="alembic.config.Config"><code class="xref py py-paramref docutils literal notranslate"><span class="pre">Config.toml_file</span></code></a> may be passed simultaneously, or
|
516
|
+
exclusively.</p>
|
517
|
+
<div class="versionadded">
|
518
|
+
<p><span class="versionmodified added">Added in version 1.16.0.</span></p>
|
519
|
+
</div>
|
520
|
+
</p></li>
|
508
521
|
<li><p><span class="target" id="alembic.config.Config.params.ini_section"></span><strong>ini_section</strong><a class="paramlink headerlink reference internal" href="#alembic.config.Config.params.ini_section">¶</a> – name of the main Alembic section within the
|
509
522
|
.ini file</p></li>
|
510
523
|
<li><p><span class="target" id="alembic.config.Config.params.output_buffer"></span><strong>output_buffer</strong><a class="paramlink headerlink reference internal" href="#alembic.config.Config.params.output_buffer">¶</a> – optional file-like input buffer which
|