├── .github ├── dependabot.yaml └── workflows │ ├── build.yml │ └── release.yml ├── .gitignore ├── CHANGELOG.md ├── LICENSE ├── Makefile ├── README.md ├── docs ├── CHANGELOG.md ├── Makefile ├── requirements.txt └── source │ ├── _static │ └── github_setting.png │ ├── api.rst │ ├── asyncio.rst │ ├── conf.py │ ├── contributing.rst │ ├── custom_data.rst │ ├── custom_tests.rst │ ├── experimental_tests.rst │ ├── index.rst │ ├── quickstart.rst │ ├── running.rst │ └── setup.rst ├── examples ├── test_alternative_script_location │ ├── alembic.ini │ ├── alembic │ │ ├── env.py │ │ ├── script.py.mako │ │ └── versions │ │ │ ├── aaaaaaaaaaaa_create_foo.py │ │ │ └── bbbbbbbbbbbb_update_foo.py │ ├── conftest.py │ └── models.py ├── test_ambiguous_downgrade_history │ ├── alembic.ini │ ├── conftest.py │ ├── migrations │ │ ├── env.py │ │ ├── script.py.mako │ │ └── versions │ │ │ ├── 10483a8dd3c8.py │ │ │ ├── 25521e40a00f.py │ │ │ ├── 68bf6c25ca140073cfa0.py │ │ │ ├── 79ee02b5e895.py │ │ │ ├── 7f5b06f81aef.py │ │ │ ├── 845c0ab60c02.py │ │ │ ├── b55e304ba00c.py │ │ │ ├── base.py │ │ │ ├── bd7be2a11e1c.py │ │ │ └── effc355fddff.py │ └── models.py ├── test_async_sqlalchemy │ ├── alembic.ini │ ├── conftest.py │ ├── migrations │ │ ├── env.py │ │ ├── script.py.mako │ │ └── versions │ │ │ ├── aaaaaaaaaaaa_create_foo.py │ │ │ └── bbbbbbbbbbbb_update_foo.py │ ├── models.py │ └── setup.cfg ├── test_async_sqlalchemy_native │ ├── alembic.ini │ ├── conftest.py │ ├── migrations │ │ ├── env.py │ │ ├── script.py.mako │ │ └── versions │ │ │ ├── aaaaaaaaaaaa_create_foo.py │ │ │ └── bbbbbbbbbbbb_update_foo.py │ ├── models.py │ └── setup.cfg ├── test_basic_revision_upgrade_data │ ├── alembic.ini │ ├── conftest.py │ ├── migrations │ │ ├── env.py │ │ ├── script.py.mako │ │ └── versions │ │ │ ├── aaaaaaaaaaaa_create_foo.py │ │ │ └── bbbbbbbbbbbb_update_foo.py │ └── models.py ├── test_branched_history │ ├── alembic.ini │ ├── conftest.py │ ├── migrations │ │ ├── env.py │ │ ├── script.py.mako │ │ └── versions │ │ │ ├── aaaaaaaaaaaa_create_foo.py │ │ │ ├── bbbbbbbbbbbb_update_foo.py │ │ │ └── cccccccccccc_create_bar.py │ ├── models.py │ ├── setup.cfg │ └── test_migrations.py ├── test_branched_history_before_upgrade_data │ ├── alembic.ini │ ├── conftest.py │ ├── migrations │ │ ├── env.py │ │ ├── script.py.mako │ │ └── versions │ │ │ ├── 70da13da0332_.py │ │ │ ├── aaaaaaaaaaaa_create_foo.py │ │ │ ├── bbbbbbbbbbbb_update_foo.py │ │ │ └── cccccccccccc_create_bar.py │ └── models.py ├── test_branched_history_with_mergepoint │ ├── alembic.ini │ ├── conftest.py │ ├── migrations │ │ ├── env.py │ │ ├── script.py.mako │ │ └── versions │ │ │ ├── 70da13da0332_.py │ │ │ ├── aaaaaaaaaaaa_create_foo.py │ │ │ ├── bbbbbbbbbbbb_update_foo.py │ │ │ └── cccccccccccc_create_bar.py │ ├── models.py │ └── test_migrations.py ├── test_complex_revision_upgrade_data │ ├── alembic.ini │ ├── conftest.py │ ├── migrations │ │ ├── env.py │ │ ├── script.py.mako │ │ └── versions │ │ │ ├── aaaaaaaaaaaa_create_foo.py │ │ │ ├── bbbbbbbbbbbb_update_foo.py │ │ │ └── cccccccccccc_update_foo.py │ └── models.py ├── test_consistency_doesnt_roundtrip │ ├── alembic.ini │ ├── conftest.py │ ├── migrations │ │ ├── env.py │ │ ├── script.py.mako │ │ └── versions │ │ │ └── aaaaaaaaaaaa_create_foo.py │ └── models.py ├── test_default_env_script │ ├── alembic.ini │ ├── conftest.py │ ├── migrations │ │ ├── script.py.mako │ │ └── versions │ │ │ ├── aaaaaaaaaaaa_create_foo.py │ │ │ └── bbbbbbbbbbbb_update_foo.py │ └── models.py ├── test_default_script_location │ ├── alembic.ini │ ├── conftest.py │ ├── migrations │ │ ├── env.py │ │ ├── script.py.mako │ │ └── versions │ │ │ ├── aaaaaaaaaaaa_create_foo.py │ │ │ └── bbbbbbbbbbbb_update_foo.py │ └── models.py ├── test_downgrade_leaves_no_trace_failure │ ├── alembic.ini │ ├── conftest.py │ ├── migrations │ │ ├── env.py │ │ ├── script.py.mako │ │ └── versions │ │ │ ├── aaaaaaaaaaaa_create_foo.py │ │ │ └── bbbbbbbbbbbb_create_foo.py │ ├── models.py │ └── setup.cfg ├── test_downgrade_leaves_no_trace_success │ ├── alembic.ini │ ├── conftest.py │ ├── migrations │ │ ├── env.py │ │ ├── script.py.mako │ │ └── versions │ │ │ └── aaaaaaaaaaaa_create_foo.py │ ├── models.py │ └── setup.cfg ├── test_empty_history │ ├── alembic.ini │ ├── conftest.py │ ├── migrations │ │ ├── env.py │ │ ├── script.py.mako │ │ └── versions │ │ │ └── .gitkeep │ ├── models.py │ └── setup.cfg ├── test_experimental_all_models_register │ ├── alembic.ini │ ├── conftest.py │ ├── migrations │ │ ├── __init__.py │ │ ├── env.py │ │ ├── script.py.mako │ │ └── versions │ │ │ ├── aaaaaaaaaaaa_create_foo.py │ │ │ └── bbbbbbbbbbbb_update_foo.py │ └── models.py ├── test_experimental_all_models_register_async │ ├── alembic.ini │ ├── conftest.py │ ├── migrations │ │ ├── env.py │ │ ├── script.py.mako │ │ └── versions │ │ │ ├── aaaaaaaaaaaa_create_foo.py │ │ │ └── bbbbbbbbbbbb_update_foo.py │ └── models.py ├── test_experimental_all_models_register_automatic │ ├── alembic.ini │ ├── conftest.py │ ├── migrations │ │ ├── __init__.py │ │ ├── env.py │ │ ├── script.py.mako │ │ └── versions │ │ │ ├── aaaaaaaaaaaa_create_foo.py │ │ │ └── bbbbbbbbbbbb_update_foo.py │ ├── models.py │ └── pyproject.toml ├── test_experimental_all_models_register_failure │ ├── alembic.ini │ ├── conftest.py │ ├── migrations │ │ ├── __init__.py │ │ ├── env.py │ │ ├── script.py.mako │ │ └── versions │ │ │ ├── aaaaaaaaaaaa_create_foo.py │ │ │ └── bbbbbbbbbbbb_update_foo.py │ └── models │ │ ├── __init__.py │ │ └── bar.py ├── test_experimental_all_models_register_metadata │ ├── alembic.ini │ ├── conftest.py │ ├── migrations │ │ ├── __init__.py │ │ ├── env.py │ │ ├── script.py.mako │ │ └── versions │ │ │ ├── aaaaaaaaaaaa_create_foo.py │ │ │ └── bbbbbbbbbbbb_update_foo.py │ └── models.py ├── test_experimental_all_models_register_namespace_package │ ├── alembic.ini │ ├── conftest.py │ ├── foo │ │ └── bar │ │ │ └── __init__.py │ ├── migrations │ │ ├── __init__.py │ │ ├── env.py │ │ ├── script.py.mako │ │ └── versions │ │ │ ├── aaaaaaaaaaaa_create_foo.py │ │ │ └── bbbbbbbbbbbb_update_foo.py │ └── pyproject.toml ├── test_experimental_all_models_register_no_metadata │ ├── alembic.ini │ ├── conftest.py │ ├── migrations │ │ ├── __init__.py │ │ ├── env.py │ │ ├── script.py.mako │ │ └── versions │ │ │ ├── aaaaaaaaaaaa_create_foo.py │ │ │ └── bbbbbbbbbbbb_update_foo.py │ └── models.py ├── test_experimental_all_models_register_offline │ ├── alembic.ini │ ├── conftest.py │ ├── migrations │ │ ├── __init__.py │ │ ├── env.py │ │ ├── script.py.mako │ │ └── versions │ │ │ ├── aaaaaaaaaaaa_create_foo.py │ │ │ └── bbbbbbbbbbbb_update_foo.py │ └── models.py ├── test_failing_downgrade │ ├── alembic.ini │ ├── conftest.py │ ├── migrations │ │ ├── env.py │ │ ├── script.py.mako │ │ └── versions │ │ │ ├── aaaaaaaaaaaa_create_foo.py │ │ │ ├── bbbbbbbbbbbb_create_foo.py │ │ │ └── cccccccccccc_create_foo.py │ ├── models.py │ └── setup.cfg ├── test_generate_revision │ ├── alembic.ini │ ├── conftest.py │ ├── migrations │ │ ├── env.py │ │ ├── script.py.mako │ │ └── versions │ │ │ └── .gitkeep │ ├── models.py │ ├── setup.cfg │ └── test_migration.py ├── test_manual_alembic_config │ ├── alembic.ini │ ├── alembic │ │ ├── env.py │ │ ├── script.py.mako │ │ └── versions │ │ │ ├── aaaaaaaaaaaa_create_foo.py │ │ │ └── bbbbbbbbbbbb_update_foo.py │ ├── conftest.py │ └── models.py ├── test_migrate_down_before │ ├── alembic.ini │ ├── conftest.py │ ├── migrations │ │ ├── env.py │ │ ├── script.py.mako │ │ └── versions │ │ │ ├── aaaaaaaaaaaa_create_foo.py │ │ │ └── bbbbbbbbbbbb_update_foo.py │ ├── models.py │ └── test_migrations.py ├── test_migrate_up_before │ ├── alembic.ini │ ├── conftest.py │ ├── migrations │ │ ├── env.py │ │ ├── script.py.mako │ │ └── versions │ │ │ ├── aaaaaaaaaaaa_create_foo.py │ │ │ └── bbbbbbbbbbbb_update_foo.py │ ├── models.py │ └── test_migrations.py ├── test_migrate_up_to │ ├── alembic.ini │ ├── conftest.py │ ├── migrations │ │ ├── env.py │ │ ├── script.py.mako │ │ └── versions │ │ │ ├── aaaaaaaaaaaa_create_foo.py │ │ │ └── bbbbbbbbbbbb_update_foo.py │ ├── models.py │ └── test_migrations.py ├── test_minimum_downgrade_revision │ ├── alembic.ini │ ├── conftest.py │ ├── migrations │ │ ├── env.py │ │ ├── script.py.mako │ │ └── versions │ │ │ ├── aaaaaaaaaaaa_create_foo.py │ │ │ ├── bbbbbbbbbbbb_create_foo.py │ │ │ ├── cccccccccccc_create_foo.py │ │ │ └── dddddddddddd_create_foo.py │ ├── models.py │ └── setup.cfg ├── test_multiple_schemata │ ├── alembic.ini │ ├── alembic2.ini │ ├── conftest.py │ ├── migrations │ │ ├── env.py │ │ ├── script.py.mako │ │ └── versions │ │ │ ├── aaaaaaaaaaaa_create_foo.py │ │ │ └── bbbbbbbbbbbb_update_foo.py │ ├── migrations2 │ │ ├── env.py │ │ ├── script.py.mako │ │ └── versions │ │ │ ├── aaaaaaaaaaaa_create_foo.py │ │ │ └── bbbbbbbbbbbb_update_foo.py │ ├── models.py │ └── models2.py ├── test_no_data │ ├── alembic.ini │ ├── conftest.py │ ├── migrations │ │ ├── env.py │ │ ├── script.py.mako │ │ └── versions │ │ │ ├── aaaaaaaaaaaa_create_foo.py │ │ │ └── bbbbbbbbbbbb_update_foo.py │ └── models.py ├── test_process_revision_directives │ ├── alembic.ini │ ├── conftest.py │ ├── migrations │ │ ├── env.py │ │ ├── script.py.mako │ │ └── versions │ │ │ ├── aaaaaaaaaaaa_create_foo.py │ │ │ └── bbbbbbbbbbbb_update_foo.py │ └── models.py ├── test_pytest_alembic_tests_path │ ├── alembic.ini │ ├── alembic │ │ ├── env.py │ │ ├── script.py.mako │ │ └── versions │ │ │ ├── aaaaaaaaaaaa_create_foo.py │ │ │ └── bbbbbbbbbbbb_update_foo.py │ ├── models │ │ └── __init__.py │ ├── pytest.ini │ └── tests_ │ │ ├── __init__.py │ │ ├── conftest.py │ │ └── test │ │ ├── __init__.py │ │ └── conftest.py ├── test_schema_revision_data │ ├── alembic.ini │ ├── conftest.py │ ├── migrations │ │ ├── env.py │ │ ├── script.py.mako │ │ └── versions │ │ │ ├── aaaaaaaaaaaa_create_foo.py │ │ │ └── bbbbbbbbbbbb_update_foo.py │ ├── models.py │ └── setup.cfg ├── test_skip_revision │ ├── alembic.ini │ ├── conftest.py │ ├── migrations │ │ ├── env.py │ │ ├── script.py.mako │ │ └── versions │ │ │ ├── aaaaaaaaaaaa_create_foo.py │ │ │ ├── bbbbbbbbbbb_raise.py │ │ │ └── cccccccccccc_success.py │ └── models.py ├── test_unimplemented_downgrade_warning │ ├── alembic.ini │ ├── conftest.py │ ├── migrations │ │ ├── env.py │ │ ├── script.py.mako │ │ └── versions │ │ │ ├── aaaaaaaaaaaa_create_foo.py │ │ │ ├── bbbbbbbbbbbb_create_foo.py │ │ │ └── cccccccccccc_create_foo.py │ ├── models.py │ └── setup.cfg └── test_version_table_schema │ ├── alembic.ini │ ├── conftest.py │ ├── migrations │ ├── env.py │ ├── script.py.mako │ └── versions │ │ ├── .gitkeep │ │ └── aaaaaaaaaaaa_create_foo.py │ ├── models.py │ └── setup.cfg ├── poetry.lock ├── pyproject.toml ├── readthedocs.yml ├── src └── pytest_alembic │ ├── __init__.py │ ├── config.py │ ├── executor.py │ ├── history.py │ ├── plugin │ ├── __init__.py │ ├── error.py │ ├── fixtures.py │ ├── hooks.py │ └── plugin.py │ ├── py.typed │ ├── revision_data.py │ ├── runner.py │ └── tests │ ├── __init__.py │ ├── default.py │ └── experimental │ ├── __init__.py │ ├── all_models_register_on_metadata.py │ ├── collect_clean_alembic_environment.py │ └── downgrade_leaves_no_trace.py └── tests ├── __init__.py ├── conftest.py ├── plugin ├── __init__.py └── test_plugin.py ├── test_config.py ├── test_executor.py ├── test_history.py ├── test_revision_data.py ├── test_runner.py └── tests ├── __init__.py └── experimental ├── __init__.py ├── test_all_models_register_on_metadata.py └── test_collect_clean_alembic_environment.py /.github/dependabot.yaml: -------------------------------------------------------------------------------- 1 | # To get started with Dependabot version updates, you'll need to specify which 2 | # package ecosystems to update and where the package manifests are located. 3 | # Please see the documentation for all configuration options: 4 | # https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates 5 | 6 | version: 2 7 | updates: 8 | - package-ecosystem: "github-actions" 9 | directory: "/" 10 | schedule: 11 | # Check for updates to GitHub Actions every week 12 | interval: "weekly" 13 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Github Release/Publish PyPi 2 | 3 | on: 4 | push: 5 | tags: 6 | - "v*.*.*" 7 | 8 | jobs: 9 | gh-release: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - name: Checkout 13 | uses: actions/checkout@v4 14 | - name: Release 15 | uses: softprops/action-gh-release@v2 16 | with: 17 | generate_release_notes: true 18 | 19 | publish-pypi: 20 | runs-on: ubuntu-latest 21 | steps: 22 | - uses: actions/checkout@v4 23 | - uses: actions/setup-python@v5 24 | with: 25 | python-version: "3.9" 26 | - name: Run image 27 | uses: abatilo/actions-poetry@v3.0.1 28 | with: 29 | poetry-version: 1.2.2 30 | 31 | - name: Publish 32 | env: 33 | PYPI_TOKEN: ${{ secrets.PYPI_TOKEN }} 34 | run: | 35 | poetry config pypi-token.pypi $PYPI_TOKEN 36 | poetry publish --build 37 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Editors 2 | .idea/ 3 | .tags* 4 | *.iml 5 | *.iws 6 | *.sublime-project 7 | *.sublime-workspace 8 | *.sw? 9 | *~ 10 | .vscode 11 | Session.vim 12 | .ropeproject/ 13 | 14 | # IPython Notebook 15 | .ipynb_checkpoints 16 | 17 | # Mac 18 | .DS_Store 19 | Icon 20 | 21 | # Distribution / packaging 22 | .Python 23 | __pycache__/ 24 | *.py[cod] 25 | *$py.class 26 | *.egg 27 | *.egg-info/ 28 | eggs/ 29 | .eggs/ 30 | .mypy_cache/ 31 | dist/ 32 | build/ 33 | pip-wheel-metadata/ 34 | 35 | # Testing 36 | .coverage 37 | .cache 38 | coverage.xml 39 | .coverage.* 40 | *.cover 41 | junit_results.xml 42 | coverage/ 43 | .pytest_cache/ 44 | 45 | # Logging 46 | log/ 47 | 48 | # Environments 49 | .env 50 | .envrc 51 | .venv 52 | env/ 53 | venv/ 54 | ENV/ 55 | env.bak/ 56 | venv.bak/ 57 | .direnv/ 58 | shell.nix 59 | 60 | # Documentation 61 | docs/_* 62 | 63 | # Generated by test runs. 64 | examples/test_generate_revision/test_migration.py 65 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: install build test lint format publish 2 | .DEFAULT_GOAL := test 3 | 4 | install: 5 | poetry install 6 | 7 | build: 8 | poetry build 9 | 10 | test: 11 | SQLALCHEMY_WARN_20=1 COVERAGE_PROCESS_START="$(PWD)/pyproject.toml" \ 12 | coverage run -m pytest src tests -vv 13 | coverage combine 14 | coverage report -i 15 | coverage xml 16 | 17 | lint: 18 | ruff src tests examples || exit 1 19 | black --check src tests examples || exit 1 20 | mypy src tests || exit 1 21 | 22 | format: 23 | ruff --fix src tests examples 24 | black src tests examples 25 | 26 | publish: build 27 | poetry publish -u __token__ -p '${PYPI_TOKEN}' --no-interaction 28 | 29 | changelog: 30 | # https://convco.github.io/ 31 | convco changelog > CHANGELOG.md 32 | -------------------------------------------------------------------------------- /docs/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ## v0.2.5 (2020-07-13) 4 | 5 | #### New Features 6 | 7 | * Allow the customization of the location at which the built in tests are executed. 8 | #### Docs 9 | 10 | * Add docs for new new config option and test running details. 11 | 12 | ## v0.2.4 (2020-07-01) 13 | 14 | #### Fixes 15 | 16 | * Require dataclasses only below 3.7, as it is included in stdlib 3.7 onward. 17 | 18 | ## v0.2.3 (2020-06-26) 19 | 20 | #### New Features 21 | 22 | * Reduce the multiple pages of traceback output to a few lines of context that are actually meaningful to a failed test. 23 | 24 | ## v0.2.2 (2020-06-25) 25 | 26 | #### New Features 27 | 28 | * Add rendered migration body to failed model-sync test. 29 | 30 | ## v0.2.1 (2020-03-23) 31 | 32 | #### Fixes 33 | 34 | * Fix deprecation pytest warning in 3.4. 35 | 36 | ## v0.1.1 (2020-03-09) 37 | 38 | 39 | ## v0.1.0 (2020-03-09) 40 | 41 | -------------------------------------------------------------------------------- /docs/Makefile: -------------------------------------------------------------------------------- 1 | # Minimal makefile for Sphinx documentation 2 | # 3 | 4 | # You can set these variables from the command line. 5 | SPHINXOPTS = 6 | SPHINXBUILD = sphinx-build 7 | SOURCEDIR = source 8 | BUILDDIR = build 9 | 10 | # Put it first so that "make" without argument is like "make help". 11 | help: 12 | @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 13 | 14 | .PHONY: help Makefile 15 | 16 | # Catch-all target: route all unknown targets to Sphinx using the new 17 | # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). 18 | %: Makefile 19 | @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 20 | 21 | livehtml: 22 | sphinx-autobuild -b html $(SOURCEDIR) $(SPHINXOPTS) $(BUILDDIR)/html 23 | -------------------------------------------------------------------------------- /docs/requirements.txt: -------------------------------------------------------------------------------- 1 | m2r2 2 | sphinx 3 | sphinx_rtd_theme 4 | sphinx_autodoc_typehints 5 | sphinx-autobuild 6 | . 7 | -------------------------------------------------------------------------------- /docs/source/_static/github_setting.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schireson/pytest-alembic/47748802f22db988fb95926189eb78ec59ad387f/docs/source/_static/github_setting.png -------------------------------------------------------------------------------- /docs/source/api.rst: -------------------------------------------------------------------------------- 1 | API 2 | === 3 | 4 | Fixtures 5 | -------- 6 | 7 | alembic_runner 8 | ~~~~~~~~~~~~~~ 9 | .. autofunction:: pytest_alembic.plugin.fixtures.alembic_runner 10 | 11 | alembic_config 12 | ~~~~~~~~~~~~~~ 13 | .. autofunction:: pytest_alembic.plugin.fixtures.alembic_config 14 | 15 | Config 16 | ++++++ 17 | .. autoclass:: pytest_alembic.config.Config 18 | :members: from_raw_config 19 | 20 | alembic_engine 21 | ~~~~~~~~~~~~~~ 22 | .. autofunction:: pytest_alembic.plugin.fixtures.alembic_engine 23 | 24 | create_alembic_fixture 25 | ~~~~~~~~~~~~~~~~~~~~~~ 26 | .. autofunction:: pytest_alembic.plugin.fixtures.create_alembic_fixture 27 | 28 | 29 | Alembic Runner 30 | -------------- 31 | 32 | The object yielded into a test from an `alembic_runner` fixture is the :class:`MigrationContext` 33 | 34 | .. automodule:: pytest_alembic.runner 35 | :members: MigrationContext 36 | 37 | .. automodule:: pytest_alembic.history 38 | :members: AlembicHistory 39 | 40 | .. automodule:: pytest_alembic.revision_data 41 | :members: RevisionData, RevisionSpec 42 | -------------------------------------------------------------------------------- /docs/source/index.rst: -------------------------------------------------------------------------------- 1 | Welcome to Pytest Alembic's documentation! 2 | ================================================ 3 | 4 | .. toctree:: 5 | :maxdepth: 2 6 | :caption: Contents: 7 | 8 | Quickstart 9 | Setup 10 | Running Tests 11 | Custom Data Hooks 12 | Custom Tests 13 | Experimental Tests 14 | Asyncio 15 | API 16 | Contributing 17 | 18 | 19 | Indices and tables 20 | ================== 21 | 22 | * :ref:`genindex` 23 | * :ref:`modindex` 24 | * :ref:`search` 25 | -------------------------------------------------------------------------------- /docs/source/quickstart.rst: -------------------------------------------------------------------------------- 1 | Quickstart 2 | ========== 3 | 4 | .. mdinclude:: ../../README.md 5 | -------------------------------------------------------------------------------- /examples/test_alternative_script_location/alembic.ini: -------------------------------------------------------------------------------- 1 | [alembic] 2 | script_location = alembic 3 | 4 | [loggers] 5 | keys = root,sqlalchemy,alembic 6 | 7 | [handlers] 8 | keys = console 9 | 10 | [formatters] 11 | keys = generic 12 | 13 | [logger_root] 14 | level = WARN 15 | handlers = console 16 | qualname = 17 | 18 | [logger_sqlalchemy] 19 | level = WARN 20 | handlers = 21 | qualname = sqlalchemy.engine 22 | 23 | [logger_alembic] 24 | level = INFO 25 | handlers = 26 | qualname = alembic 27 | 28 | [handler_console] 29 | class = StreamHandler 30 | args = (sys.stderr,) 31 | level = NOTSET 32 | formatter = generic 33 | 34 | [formatter_generic] 35 | format = %(levelname)-5.5s [%(name)s] %(message)s 36 | datefmt = %H:%M:%S 37 | -------------------------------------------------------------------------------- /examples/test_alternative_script_location/alembic/env.py: -------------------------------------------------------------------------------- 1 | from logging.config import fileConfig 2 | 3 | from alembic import context 4 | from models import Base 5 | from sqlalchemy import engine_from_config, pool 6 | 7 | fileConfig(context.config.config_file_name) 8 | target_metadata = Base.metadata 9 | 10 | 11 | connectable = context.config.attributes.get("connection", None) 12 | 13 | if connectable is None: 14 | connectable = engine_from_config( 15 | context.config.get_section(context.config.config_ini_section), 16 | prefix="sqlalchemy.", 17 | poolclass=pool.NullPool, 18 | ) 19 | 20 | with connectable.connect() as connection: 21 | context.configure(connection=connection, target_metadata=target_metadata) 22 | 23 | with context.begin_transaction(): 24 | context.run_migrations() 25 | -------------------------------------------------------------------------------- /examples/test_alternative_script_location/alembic/script.py.mako: -------------------------------------------------------------------------------- 1 | """${message} 2 | 3 | Revision ID: ${up_revision} 4 | Revises: ${down_revision | comma,n} 5 | Create Date: ${create_date} 6 | 7 | """ 8 | from alembic import op 9 | import sqlalchemy as sa 10 | ${imports if imports else ""} 11 | 12 | # revision identifiers, used by Alembic. 13 | revision = ${repr(up_revision)} 14 | down_revision = ${repr(down_revision)} 15 | branch_labels = ${repr(branch_labels)} 16 | depends_on = ${repr(depends_on)} 17 | 18 | 19 | def upgrade(): 20 | ${upgrades if upgrades else "pass"} 21 | 22 | 23 | def downgrade(): 24 | ${downgrades if downgrades else "pass"} 25 | -------------------------------------------------------------------------------- /examples/test_alternative_script_location/alembic/versions/aaaaaaaaaaaa_create_foo.py: -------------------------------------------------------------------------------- 1 | import sqlalchemy as sa 2 | from alembic import op 3 | 4 | revision = "aaaaaaaaaaaa" 5 | down_revision = None 6 | branch_labels = None 7 | depends_on = None 8 | 9 | 10 | def upgrade(): 11 | op.create_table( 12 | "foo", 13 | sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), 14 | sa.Column( 15 | "created_at", 16 | sa.DateTime(timezone=True), 17 | server_default=sa.text("(CURRENT_TIMESTAMP)"), 18 | nullable=False, 19 | ), 20 | sa.PrimaryKeyConstraint("id"), 21 | ) 22 | 23 | 24 | def downgrade(): 25 | op.drop_table("foo") 26 | -------------------------------------------------------------------------------- /examples/test_alternative_script_location/alembic/versions/bbbbbbbbbbbb_update_foo.py: -------------------------------------------------------------------------------- 1 | from alembic import op 2 | from sqlalchemy import text 3 | 4 | revision = "bbbbbbbbbbbb" 5 | down_revision = "aaaaaaaaaaaa" 6 | branch_labels = None 7 | depends_on = None 8 | 9 | 10 | def upgrade(): 11 | conn = op.get_bind() 12 | result = conn.execute(text("SELECT * FROM foo")).fetchall() 13 | assert len(result) == 0 14 | 15 | 16 | def downgrade(): 17 | pass 18 | -------------------------------------------------------------------------------- /examples/test_alternative_script_location/conftest.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schireson/pytest-alembic/47748802f22db988fb95926189eb78ec59ad387f/examples/test_alternative_script_location/conftest.py -------------------------------------------------------------------------------- /examples/test_alternative_script_location/models.py: -------------------------------------------------------------------------------- 1 | import sqlalchemy 2 | from sqlalchemy import Column, types 3 | 4 | try: 5 | from sqlalchemy.orm import declarative_base 6 | except ImportError: 7 | from sqlalchemy.ext.declarative import declarative_base 8 | 9 | 10 | Base = declarative_base() 11 | 12 | 13 | class CreatedAt(Base): 14 | __tablename__ = "foo" 15 | 16 | id = Column(types.Integer(), autoincrement=True, primary_key=True) 17 | 18 | created_at = sqlalchemy.Column( 19 | sqlalchemy.types.DateTime(timezone=True), 20 | server_default=sqlalchemy.text("CURRENT_TIMESTAMP"), 21 | nullable=False, 22 | ) 23 | -------------------------------------------------------------------------------- /examples/test_ambiguous_downgrade_history/alembic.ini: -------------------------------------------------------------------------------- 1 | [alembic] 2 | script_location = migrations 3 | 4 | [loggers] 5 | keys = root,sqlalchemy,alembic 6 | 7 | [handlers] 8 | keys = console 9 | 10 | [formatters] 11 | keys = generic 12 | 13 | [logger_root] 14 | level = WARN 15 | handlers = console 16 | qualname = 17 | 18 | [logger_sqlalchemy] 19 | level = WARN 20 | handlers = 21 | qualname = sqlalchemy.engine 22 | 23 | [logger_alembic] 24 | level = INFO 25 | handlers = 26 | qualname = alembic 27 | 28 | [handler_console] 29 | class = StreamHandler 30 | args = (sys.stderr,) 31 | level = NOTSET 32 | formatter = generic 33 | 34 | [formatter_generic] 35 | format = %(levelname)-5.5s [%(name)s] %(message)s 36 | datefmt = %H:%M:%S 37 | -------------------------------------------------------------------------------- /examples/test_ambiguous_downgrade_history/conftest.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schireson/pytest-alembic/47748802f22db988fb95926189eb78ec59ad387f/examples/test_ambiguous_downgrade_history/conftest.py -------------------------------------------------------------------------------- /examples/test_ambiguous_downgrade_history/migrations/env.py: -------------------------------------------------------------------------------- 1 | from logging.config import fileConfig 2 | 3 | from alembic import context 4 | from models import Base 5 | from sqlalchemy import engine_from_config, pool 6 | 7 | fileConfig(context.config.config_file_name) 8 | target_metadata = Base.metadata 9 | 10 | 11 | connectable = context.config.attributes.get("connection", None) 12 | 13 | if connectable is None: 14 | connectable = engine_from_config( 15 | context.config.get_section(context.config.config_ini_section), 16 | prefix="sqlalchemy.", 17 | poolclass=pool.NullPool, 18 | ) 19 | 20 | with connectable.connect() as connection: 21 | context.configure(connection=connection, target_metadata=target_metadata) 22 | 23 | with context.begin_transaction(): 24 | context.run_migrations() 25 | -------------------------------------------------------------------------------- /examples/test_ambiguous_downgrade_history/migrations/script.py.mako: -------------------------------------------------------------------------------- 1 | """${message} 2 | 3 | Revision ID: ${up_revision} 4 | Revises: ${down_revision | comma,n} 5 | Create Date: ${create_date} 6 | 7 | """ 8 | from alembic import op 9 | import sqlalchemy as sa 10 | ${imports if imports else ""} 11 | 12 | # revision identifiers, used by Alembic. 13 | revision = ${repr(up_revision)} 14 | down_revision = ${repr(down_revision)} 15 | branch_labels = ${repr(branch_labels)} 16 | depends_on = ${repr(depends_on)} 17 | 18 | 19 | def upgrade(): 20 | ${upgrades if upgrades else "pass"} 21 | 22 | 23 | def downgrade(): 24 | ${downgrades if downgrades else "pass"} 25 | -------------------------------------------------------------------------------- /examples/test_ambiguous_downgrade_history/migrations/versions/10483a8dd3c8.py: -------------------------------------------------------------------------------- 1 | """Revision ID: 10483a8dd3c8 2 | Revises: first 3 | Create Date: 2020-07-01 16:44:05.244310. 4 | """ 5 | # revision identifiers, used by Alembic. 6 | revision = "10483a8dd3c8" 7 | down_revision = "first" 8 | branch_labels = None 9 | depends_on = None 10 | 11 | 12 | def upgrade(): 13 | pass 14 | 15 | 16 | def downgrade(): 17 | pass 18 | -------------------------------------------------------------------------------- /examples/test_ambiguous_downgrade_history/migrations/versions/25521e40a00f.py: -------------------------------------------------------------------------------- 1 | """Revision ID: 25521e40a00f 2 | Revises: b55e304ba00c, bd7be2a11e1c 3 | Create Date: 2020-07-01 16:44:05.244310. 4 | """ 5 | # revision identifiers, used by Alembic. 6 | revision = "25521e40a00f" 7 | down_revision = ["b55e304ba00c", "bd7be2a11e1c"] 8 | branch_labels = None 9 | depends_on = None 10 | 11 | 12 | def upgrade(): 13 | pass 14 | 15 | 16 | def downgrade(): 17 | pass 18 | -------------------------------------------------------------------------------- /examples/test_ambiguous_downgrade_history/migrations/versions/68bf6c25ca140073cfa0.py: -------------------------------------------------------------------------------- 1 | """Revision ID: 68bf6c25ca140073cfa0 2 | Revises: first 3 | Create Date: 2020-07-01 16:44:05.244310. 4 | """ 5 | # revision identifiers, used by Alembic. 6 | revision = "68bf6c25ca140073cfa0" 7 | down_revision = "first" 8 | branch_labels = None 9 | depends_on = None 10 | 11 | 12 | def upgrade(): 13 | pass 14 | 15 | 16 | def downgrade(): 17 | pass 18 | -------------------------------------------------------------------------------- /examples/test_ambiguous_downgrade_history/migrations/versions/79ee02b5e895.py: -------------------------------------------------------------------------------- 1 | """Revision ID: 79ee02b5e895 2 | Revises: 10483a8dd3c8, effc355fddff 3 | Create Date: 2020-07-01 16:44:05.244310. 4 | """ 5 | # revision identifiers, used by Alembic. 6 | revision = "79ee02b5e895" 7 | down_revision = ("10483a8dd3c8", "effc355fddff") 8 | branch_labels = None 9 | depends_on = None 10 | 11 | 12 | def upgrade(): 13 | pass 14 | 15 | 16 | def downgrade(): 17 | pass 18 | -------------------------------------------------------------------------------- /examples/test_ambiguous_downgrade_history/migrations/versions/7f5b06f81aef.py: -------------------------------------------------------------------------------- 1 | """Revision ID: 7f5b06f81aef 2 | Revises: effc355fddff 3 | Create Date: 2020-07-01 16:44:05.244310. 4 | """ 5 | # revision identifiers, used by Alembic. 6 | revision = "7f5b06f81aef" 7 | down_revision = "effc355fddff" 8 | branch_labels = None 9 | depends_on = None 10 | 11 | 12 | def upgrade(): 13 | pass 14 | 15 | 16 | def downgrade(): 17 | pass 18 | -------------------------------------------------------------------------------- /examples/test_ambiguous_downgrade_history/migrations/versions/845c0ab60c02.py: -------------------------------------------------------------------------------- 1 | """Revision ID: 845c0ab60c02 2 | Revises: 7f5b06f81aef, 68bf6c25ca140073cfa0 3 | Create Date: 2020-07-01 16:44:05.244310. 4 | """ 5 | # revision identifiers, used by Alembic. 6 | revision = "845c0ab60c02" 7 | down_revision = ("7f5b06f81aef", "68bf6c25ca140073cfa0") 8 | branch_labels = None 9 | depends_on = None 10 | 11 | 12 | def upgrade(): 13 | pass 14 | 15 | 16 | def downgrade(): 17 | pass 18 | -------------------------------------------------------------------------------- /examples/test_ambiguous_downgrade_history/migrations/versions/b55e304ba00c.py: -------------------------------------------------------------------------------- 1 | """Revision ID: b55e304ba00c 2 | Revises: 7f5b06f81aef, 79ee02b5e895 3 | Create Date: 2020-07-01 16:44:05.244310. 4 | """ 5 | # revision identifiers, used by Alembic. 6 | revision = "b55e304ba00c" 7 | down_revision = ("7f5b06f81aef", "79ee02b5e895") 8 | branch_labels = None 9 | depends_on = None 10 | 11 | 12 | def upgrade(): 13 | pass 14 | 15 | 16 | def downgrade(): 17 | pass 18 | -------------------------------------------------------------------------------- /examples/test_ambiguous_downgrade_history/migrations/versions/base.py: -------------------------------------------------------------------------------- 1 | """Revision ID: first 2 | Revises: 3 | Create Date: 2020-07-01 16:44:05.244310. 4 | """ 5 | # revision identifiers, used by Alembic. 6 | revision = "first" 7 | down_revision = None 8 | branch_labels = None 9 | depends_on = None 10 | 11 | 12 | def upgrade(): 13 | pass 14 | 15 | 16 | def downgrade(): 17 | pass 18 | -------------------------------------------------------------------------------- /examples/test_ambiguous_downgrade_history/migrations/versions/bd7be2a11e1c.py: -------------------------------------------------------------------------------- 1 | """Revision ID: bd7be2a11e1c 2 | Revises: 845c0ab60c02 3 | Create Date: 2020-07-01 16:44:05.244310. 4 | """ 5 | # revision identifiers, used by Alembic. 6 | revision = "bd7be2a11e1c" 7 | down_revision = "845c0ab60c02" 8 | branch_labels = None 9 | depends_on = None 10 | 11 | 12 | def upgrade(): 13 | pass 14 | 15 | 16 | def downgrade(): 17 | pass 18 | -------------------------------------------------------------------------------- /examples/test_ambiguous_downgrade_history/migrations/versions/effc355fddff.py: -------------------------------------------------------------------------------- 1 | """Revision ID: effc355fddff 2 | Revises: first 3 | Create Date: 2020-07-01 16:44:05.244310. 4 | """ 5 | # revision identifiers, used by Alembic. 6 | revision = "effc355fddff" 7 | down_revision = "first" 8 | branch_labels = None 9 | depends_on = None 10 | 11 | 12 | def upgrade(): 13 | pass 14 | 15 | 16 | def downgrade(): 17 | pass 18 | -------------------------------------------------------------------------------- /examples/test_ambiguous_downgrade_history/models.py: -------------------------------------------------------------------------------- 1 | try: 2 | from sqlalchemy.orm import declarative_base 3 | except ImportError: 4 | from sqlalchemy.ext.declarative import declarative_base 5 | 6 | 7 | Base = declarative_base() 8 | -------------------------------------------------------------------------------- /examples/test_async_sqlalchemy/alembic.ini: -------------------------------------------------------------------------------- 1 | [alembic] 2 | script_location = migrations 3 | 4 | [loggers] 5 | keys = root,sqlalchemy,alembic 6 | 7 | [handlers] 8 | keys = console 9 | 10 | [formatters] 11 | keys = generic 12 | 13 | [logger_root] 14 | level = WARN 15 | handlers = console 16 | qualname = 17 | 18 | [logger_sqlalchemy] 19 | level = WARN 20 | handlers = 21 | qualname = sqlalchemy.engine 22 | 23 | [logger_alembic] 24 | level = INFO 25 | handlers = 26 | qualname = alembic 27 | 28 | [handler_console] 29 | class = StreamHandler 30 | args = (sys.stderr,) 31 | level = NOTSET 32 | formatter = generic 33 | 34 | [formatter_generic] 35 | format = %(levelname)-5.5s [%(name)s] %(message)s 36 | datefmt = %H:%M:%S 37 | -------------------------------------------------------------------------------- /examples/test_async_sqlalchemy/conftest.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | import pytest_asyncio 3 | from pytest_mock_resources import create_postgres_fixture 4 | from sqlalchemy.engine.url import URL 5 | from sqlalchemy.ext.asyncio import create_async_engine 6 | 7 | pg = create_postgres_fixture() 8 | 9 | 10 | try: 11 | fixture = pytest_asyncio.fixture 12 | except AttributeError: 13 | fixture = pytest.fixture 14 | 15 | 16 | @fixture 17 | def alembic_engine(pg): 18 | creds = pg.pmr_credentials 19 | url = URL.create( 20 | drivername="postgresql+asyncpg", 21 | username=creds.username, 22 | password=creds.password, 23 | host=creds.host, 24 | port=creds.port, 25 | database=creds.database, 26 | ) 27 | return create_async_engine(url) 28 | -------------------------------------------------------------------------------- /examples/test_async_sqlalchemy/migrations/script.py.mako: -------------------------------------------------------------------------------- 1 | """${message} 2 | 3 | Revision ID: ${up_revision} 4 | Revises: ${down_revision | comma,n} 5 | Create Date: ${create_date} 6 | 7 | """ 8 | from alembic import op 9 | import sqlalchemy as sa 10 | ${imports if imports else ""} 11 | 12 | # revision identifiers, used by Alembic. 13 | revision = ${repr(up_revision)} 14 | down_revision = ${repr(down_revision)} 15 | branch_labels = ${repr(branch_labels)} 16 | depends_on = ${repr(depends_on)} 17 | 18 | 19 | def upgrade(): 20 | ${upgrades if upgrades else "pass"} 21 | 22 | 23 | def downgrade(): 24 | ${downgrades if downgrades else "pass"} 25 | -------------------------------------------------------------------------------- /examples/test_async_sqlalchemy/migrations/versions/aaaaaaaaaaaa_create_foo.py: -------------------------------------------------------------------------------- 1 | import sqlalchemy as sa 2 | from alembic import op 3 | 4 | revision = "aaaaaaaaaaaa" 5 | down_revision = None 6 | branch_labels = None 7 | depends_on = None 8 | 9 | 10 | def upgrade(): 11 | op.create_table( 12 | "foo", 13 | sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), 14 | sa.Column( 15 | "created_at", 16 | sa.DateTime(timezone=True), 17 | server_default=sa.text("(CURRENT_TIMESTAMP)"), 18 | nullable=False, 19 | ), 20 | sa.PrimaryKeyConstraint("id"), 21 | ) 22 | 23 | 24 | def downgrade(): 25 | op.drop_table("foo") 26 | -------------------------------------------------------------------------------- /examples/test_async_sqlalchemy/migrations/versions/bbbbbbbbbbbb_update_foo.py: -------------------------------------------------------------------------------- 1 | from alembic import op 2 | from sqlalchemy import text 3 | 4 | revision = "bbbbbbbbbbbb" 5 | down_revision = "aaaaaaaaaaaa" 6 | branch_labels = None 7 | depends_on = None 8 | 9 | 10 | def upgrade(): 11 | conn = op.get_bind() 12 | result = conn.execute(text("SELECT * FROM foo")).fetchall() 13 | assert len(result) == 0 14 | 15 | 16 | def downgrade(): 17 | pass 18 | -------------------------------------------------------------------------------- /examples/test_async_sqlalchemy/models.py: -------------------------------------------------------------------------------- 1 | import sqlalchemy 2 | from sqlalchemy import Column, types 3 | 4 | try: 5 | from sqlalchemy.orm import declarative_base 6 | except ImportError: 7 | from sqlalchemy.ext.declarative import declarative_base 8 | 9 | 10 | Base = declarative_base() 11 | 12 | 13 | class CreatedAt(Base): 14 | __tablename__ = "foo" 15 | 16 | id = Column(types.Integer(), autoincrement=True, primary_key=True) 17 | 18 | created_at = sqlalchemy.Column( 19 | sqlalchemy.types.DateTime(timezone=True), 20 | server_default=sqlalchemy.text("CURRENT_TIMESTAMP"), 21 | nullable=False, 22 | ) 23 | -------------------------------------------------------------------------------- /examples/test_async_sqlalchemy/setup.cfg: -------------------------------------------------------------------------------- 1 | [tool:pytest] 2 | asyncio_mode = auto 3 | -------------------------------------------------------------------------------- /examples/test_async_sqlalchemy_native/alembic.ini: -------------------------------------------------------------------------------- 1 | 2 | [alembic] 3 | script_location = migrations 4 | 5 | [loggers] 6 | keys = root,sqlalchemy,alembic 7 | 8 | [handlers] 9 | keys = console 10 | 11 | [formatters] 12 | keys = generic 13 | 14 | [logger_root] 15 | level = WARN 16 | handlers = console 17 | qualname = 18 | 19 | [logger_sqlalchemy] 20 | level = WARN 21 | handlers = 22 | qualname = sqlalchemy.engine 23 | 24 | [logger_alembic] 25 | level = INFO 26 | handlers = 27 | qualname = alembic 28 | 29 | [handler_console] 30 | class = StreamHandler 31 | args = (sys.stderr,) 32 | level = NOTSET 33 | formatter = generic 34 | 35 | [formatter_generic] 36 | format = %(levelname)-5.5s [%(name)s] %(message)s 37 | datefmt = %H:%M:%S 38 | -------------------------------------------------------------------------------- /examples/test_async_sqlalchemy_native/conftest.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | from pytest_mock_resources import create_postgres_fixture 3 | 4 | alembic_engine = create_postgres_fixture(async_=True) 5 | 6 | 7 | @pytest.fixture() 8 | def alembic_config(): 9 | return {"before_revision_data": {"bbbbbbbbbbbb": {"__tablename__": "foo", "id": 9}}} 10 | -------------------------------------------------------------------------------- /examples/test_async_sqlalchemy_native/migrations/script.py.mako: -------------------------------------------------------------------------------- 1 | """${message} 2 | 3 | Revision ID: ${up_revision} 4 | Revises: ${down_revision | comma,n} 5 | Create Date: ${create_date} 6 | 7 | """ 8 | from alembic import op 9 | import sqlalchemy as sa 10 | ${imports if imports else ""} 11 | 12 | # revision identifiers, used by Alembic. 13 | revision = ${repr(up_revision)} 14 | down_revision = ${repr(down_revision)} 15 | branch_labels = ${repr(branch_labels)} 16 | depends_on = ${repr(depends_on)} 17 | 18 | 19 | def upgrade(): 20 | ${upgrades if upgrades else "pass"} 21 | 22 | 23 | def downgrade(): 24 | ${downgrades if downgrades else "pass"} 25 | -------------------------------------------------------------------------------- /examples/test_async_sqlalchemy_native/migrations/versions/aaaaaaaaaaaa_create_foo.py: -------------------------------------------------------------------------------- 1 | import sqlalchemy as sa 2 | from alembic import op 3 | 4 | revision = "aaaaaaaaaaaa" 5 | down_revision = None 6 | branch_labels = None 7 | depends_on = None 8 | 9 | 10 | def upgrade(): 11 | op.create_table( 12 | "foo", 13 | sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), 14 | sa.Column( 15 | "created_at", 16 | sa.DateTime(timezone=True), 17 | server_default=sa.text("(CURRENT_TIMESTAMP)"), 18 | nullable=False, 19 | ), 20 | sa.PrimaryKeyConstraint("id"), 21 | ) 22 | 23 | 24 | def downgrade(): 25 | op.drop_table("foo") 26 | -------------------------------------------------------------------------------- /examples/test_async_sqlalchemy_native/migrations/versions/bbbbbbbbbbbb_update_foo.py: -------------------------------------------------------------------------------- 1 | from alembic import op 2 | from sqlalchemy import text 3 | 4 | revision = "bbbbbbbbbbbb" 5 | down_revision = "aaaaaaaaaaaa" 6 | branch_labels = None 7 | depends_on = None 8 | 9 | 10 | def upgrade(): 11 | conn = op.get_bind() 12 | result = conn.execute(text("SELECT * FROM foo")).fetchall() 13 | assert len(result) == 1, result 14 | 15 | 16 | def downgrade(): 17 | pass 18 | -------------------------------------------------------------------------------- /examples/test_async_sqlalchemy_native/models.py: -------------------------------------------------------------------------------- 1 | import sqlalchemy 2 | from sqlalchemy import Column, types 3 | 4 | try: 5 | from sqlalchemy.orm import declarative_base 6 | except ImportError: 7 | from sqlalchemy.ext.declarative import declarative_base 8 | 9 | 10 | Base = declarative_base() 11 | 12 | 13 | class CreatedAt(Base): 14 | __tablename__ = "foo" 15 | 16 | id = Column(types.Integer(), autoincrement=True, primary_key=True) 17 | 18 | created_at = sqlalchemy.Column( 19 | sqlalchemy.types.DateTime(timezone=True), 20 | server_default=sqlalchemy.text("CURRENT_TIMESTAMP"), 21 | nullable=False, 22 | ) 23 | -------------------------------------------------------------------------------- /examples/test_async_sqlalchemy_native/setup.cfg: -------------------------------------------------------------------------------- 1 | [tool:pytest] 2 | pytest_alembic_include_experimental = downgrade_leaves_no_trace,all_models_register_on_metadata 3 | -------------------------------------------------------------------------------- /examples/test_basic_revision_upgrade_data/alembic.ini: -------------------------------------------------------------------------------- 1 | [alembic] 2 | script_location = migrations 3 | 4 | [loggers] 5 | keys = root,sqlalchemy,alembic 6 | 7 | [handlers] 8 | keys = console 9 | 10 | [formatters] 11 | keys = generic 12 | 13 | [logger_root] 14 | level = WARN 15 | handlers = console 16 | qualname = 17 | 18 | [logger_sqlalchemy] 19 | level = WARN 20 | handlers = 21 | qualname = sqlalchemy.engine 22 | 23 | [logger_alembic] 24 | level = INFO 25 | handlers = 26 | qualname = alembic 27 | 28 | [handler_console] 29 | class = StreamHandler 30 | args = (sys.stderr,) 31 | level = NOTSET 32 | formatter = generic 33 | 34 | [formatter_generic] 35 | format = %(levelname)-5.5s [%(name)s] %(message)s 36 | datefmt = %H:%M:%S 37 | -------------------------------------------------------------------------------- /examples/test_basic_revision_upgrade_data/conftest.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | 3 | 4 | @pytest.fixture() 5 | def alembic_config(): 6 | return {"before_revision_data": {"bbbbbbbbbbbb": {"__tablename__": "foo", "id": 9}}} 7 | -------------------------------------------------------------------------------- /examples/test_basic_revision_upgrade_data/migrations/env.py: -------------------------------------------------------------------------------- 1 | from logging.config import fileConfig 2 | 3 | from alembic import context 4 | from models import Base 5 | from sqlalchemy import engine_from_config, pool 6 | 7 | fileConfig(context.config.config_file_name) 8 | target_metadata = Base.metadata 9 | 10 | 11 | connectable = context.config.attributes.get("connection", None) 12 | 13 | if connectable is None: 14 | connectable = engine_from_config( 15 | context.config.get_section(context.config.config_ini_section), 16 | prefix="sqlalchemy.", 17 | poolclass=pool.NullPool, 18 | ) 19 | 20 | with connectable.connect() as connection: 21 | context.configure(connection=connection, target_metadata=target_metadata) 22 | 23 | with context.begin_transaction(): 24 | context.run_migrations() 25 | -------------------------------------------------------------------------------- /examples/test_basic_revision_upgrade_data/migrations/script.py.mako: -------------------------------------------------------------------------------- 1 | """${message} 2 | 3 | Revision ID: ${up_revision} 4 | Revises: ${down_revision | comma,n} 5 | Create Date: ${create_date} 6 | 7 | """ 8 | from alembic import op 9 | import sqlalchemy as sa 10 | ${imports if imports else ""} 11 | 12 | # revision identifiers, used by Alembic. 13 | revision = ${repr(up_revision)} 14 | down_revision = ${repr(down_revision)} 15 | branch_labels = ${repr(branch_labels)} 16 | depends_on = ${repr(depends_on)} 17 | 18 | 19 | def upgrade(): 20 | ${upgrades if upgrades else "pass"} 21 | 22 | 23 | def downgrade(): 24 | ${downgrades if downgrades else "pass"} 25 | -------------------------------------------------------------------------------- /examples/test_basic_revision_upgrade_data/migrations/versions/aaaaaaaaaaaa_create_foo.py: -------------------------------------------------------------------------------- 1 | import sqlalchemy as sa 2 | from alembic import op 3 | 4 | revision = "aaaaaaaaaaaa" 5 | down_revision = None 6 | branch_labels = None 7 | depends_on = None 8 | 9 | 10 | def upgrade(): 11 | op.create_table( 12 | "foo", 13 | sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), 14 | sa.Column( 15 | "created_at", 16 | sa.DateTime(timezone=True), 17 | server_default=sa.text("(CURRENT_TIMESTAMP)"), 18 | nullable=False, 19 | ), 20 | sa.PrimaryKeyConstraint("id"), 21 | ) 22 | 23 | 24 | def downgrade(): 25 | op.drop_table("foo") 26 | -------------------------------------------------------------------------------- /examples/test_basic_revision_upgrade_data/migrations/versions/bbbbbbbbbbbb_update_foo.py: -------------------------------------------------------------------------------- 1 | from alembic import op 2 | from sqlalchemy import text 3 | 4 | revision = "bbbbbbbbbbbb" 5 | down_revision = "aaaaaaaaaaaa" 6 | branch_labels = None 7 | depends_on = None 8 | 9 | 10 | def upgrade(): 11 | conn = op.get_bind() 12 | result = conn.execute(text("SELECT * FROM foo")).fetchall() 13 | assert len(result) == 1 14 | assert result[0].id == 9, f"{result[0].id} == 9" 15 | 16 | 17 | def downgrade(): 18 | pass 19 | -------------------------------------------------------------------------------- /examples/test_basic_revision_upgrade_data/models.py: -------------------------------------------------------------------------------- 1 | import sqlalchemy 2 | from sqlalchemy import Column, types 3 | 4 | try: 5 | from sqlalchemy.orm import declarative_base 6 | except ImportError: 7 | from sqlalchemy.ext.declarative import declarative_base 8 | 9 | 10 | Base = declarative_base() 11 | 12 | 13 | class CreatedAt(Base): 14 | __tablename__ = "foo" 15 | 16 | id = Column(types.Integer(), autoincrement=True, primary_key=True) 17 | 18 | created_at = sqlalchemy.Column( 19 | sqlalchemy.types.DateTime(timezone=True), 20 | server_default=sqlalchemy.text("CURRENT_TIMESTAMP"), 21 | nullable=False, 22 | ) 23 | -------------------------------------------------------------------------------- /examples/test_branched_history/alembic.ini: -------------------------------------------------------------------------------- 1 | [alembic] 2 | script_location = migrations 3 | 4 | [loggers] 5 | keys = root,sqlalchemy,alembic 6 | 7 | [handlers] 8 | keys = console 9 | 10 | [formatters] 11 | keys = generic 12 | 13 | [logger_root] 14 | level = WARN 15 | handlers = console 16 | qualname = 17 | 18 | [logger_sqlalchemy] 19 | level = WARN 20 | handlers = 21 | qualname = sqlalchemy.engine 22 | 23 | [logger_alembic] 24 | level = INFO 25 | handlers = 26 | qualname = alembic 27 | 28 | [handler_console] 29 | class = StreamHandler 30 | args = (sys.stderr,) 31 | level = NOTSET 32 | formatter = generic 33 | 34 | [formatter_generic] 35 | format = %(levelname)-5.5s [%(name)s] %(message)s 36 | datefmt = %H:%M:%S 37 | -------------------------------------------------------------------------------- /examples/test_branched_history/conftest.py: -------------------------------------------------------------------------------- 1 | from pytest_mock_resources import create_postgres_fixture 2 | 3 | alembic_engine = create_postgres_fixture() 4 | -------------------------------------------------------------------------------- /examples/test_branched_history/migrations/env.py: -------------------------------------------------------------------------------- 1 | from logging.config import fileConfig 2 | 3 | from alembic import context 4 | from models import Base 5 | from sqlalchemy import engine_from_config, pool 6 | 7 | fileConfig(context.config.config_file_name) 8 | target_metadata = Base.metadata 9 | 10 | 11 | connectable = context.config.attributes.get("connection", None) 12 | 13 | if connectable is None: 14 | connectable = engine_from_config( 15 | context.config.get_section(context.config.config_ini_section), 16 | prefix="sqlalchemy.", 17 | poolclass=pool.NullPool, 18 | ) 19 | 20 | with connectable.connect() as connection: 21 | context.configure(connection=connection, target_metadata=target_metadata) 22 | 23 | with context.begin_transaction(): 24 | context.run_migrations() 25 | -------------------------------------------------------------------------------- /examples/test_branched_history/migrations/script.py.mako: -------------------------------------------------------------------------------- 1 | """${message} 2 | 3 | Revision ID: ${up_revision} 4 | Revises: ${down_revision | comma,n} 5 | Create Date: ${create_date} 6 | 7 | """ 8 | from alembic import op 9 | import sqlalchemy as sa 10 | ${imports if imports else ""} 11 | 12 | # revision identifiers, used by Alembic. 13 | revision = ${repr(up_revision)} 14 | down_revision = ${repr(down_revision)} 15 | branch_labels = ${repr(branch_labels)} 16 | depends_on = ${repr(depends_on)} 17 | 18 | 19 | def upgrade(): 20 | ${upgrades if upgrades else "pass"} 21 | 22 | 23 | def downgrade(): 24 | ${downgrades if downgrades else "pass"} 25 | -------------------------------------------------------------------------------- /examples/test_branched_history/migrations/versions/aaaaaaaaaaaa_create_foo.py: -------------------------------------------------------------------------------- 1 | import sqlalchemy as sa 2 | from alembic import op 3 | 4 | revision = "aaaaaaaaaaaa" 5 | down_revision = None 6 | branch_labels = None 7 | depends_on = None 8 | 9 | 10 | def upgrade(): 11 | op.create_table( 12 | "foo", 13 | sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), 14 | sa.PrimaryKeyConstraint("id"), 15 | ) 16 | 17 | 18 | def downgrade(): 19 | op.drop_table("foo") 20 | -------------------------------------------------------------------------------- /examples/test_branched_history/migrations/versions/bbbbbbbbbbbb_update_foo.py: -------------------------------------------------------------------------------- 1 | import sqlalchemy as sa 2 | from alembic import op 3 | 4 | revision = "bbbbbbbbbbbb" 5 | down_revision = "aaaaaaaaaaaa" 6 | branch_labels = None 7 | depends_on = None 8 | 9 | 10 | def upgrade(): 11 | op.add_column( 12 | "foo", 13 | sa.Column( 14 | "created_at", 15 | sa.DateTime(timezone=True), 16 | server_default=sa.text("'2020-01-01'"), 17 | nullable=False, 18 | ), 19 | ) 20 | 21 | 22 | def downgrade(): 23 | op.drop_column("foo", "created_at") 24 | -------------------------------------------------------------------------------- /examples/test_branched_history/migrations/versions/cccccccccccc_create_bar.py: -------------------------------------------------------------------------------- 1 | import sqlalchemy as sa 2 | from alembic import op 3 | 4 | revision = "cccccccccccc" 5 | down_revision = "aaaaaaaaaaaa" 6 | branch_labels = None 7 | depends_on = None 8 | 9 | 10 | def upgrade(): 11 | op.create_table( 12 | "bar", 13 | sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), 14 | sa.PrimaryKeyConstraint("id"), 15 | ) 16 | 17 | 18 | def downgrade(): 19 | op.drop_table("bar") 20 | -------------------------------------------------------------------------------- /examples/test_branched_history/models.py: -------------------------------------------------------------------------------- 1 | import sqlalchemy 2 | from sqlalchemy import Column, types 3 | 4 | try: 5 | from sqlalchemy.orm import declarative_base 6 | except ImportError: 7 | from sqlalchemy.ext.declarative import declarative_base 8 | 9 | 10 | Base = declarative_base() 11 | 12 | 13 | class CreatedAt(Base): 14 | __tablename__ = "foo" 15 | 16 | id = Column(types.Integer(), autoincrement=True, primary_key=True) 17 | 18 | created_at = sqlalchemy.Column( 19 | sqlalchemy.types.DateTime(timezone=True), 20 | server_default=sqlalchemy.text("'2020-01-01'"), 21 | nullable=False, 22 | ) 23 | 24 | 25 | class Bar(Base): 26 | __tablename__ = "bar" 27 | 28 | id = Column(types.Integer(), autoincrement=True, primary_key=True) 29 | -------------------------------------------------------------------------------- /examples/test_branched_history/setup.cfg: -------------------------------------------------------------------------------- 1 | [tool:pytest] 2 | pytest_alembic_exclude = single_head_revision 3 | -------------------------------------------------------------------------------- /examples/test_branched_history/test_migrations.py: -------------------------------------------------------------------------------- 1 | from sqlalchemy import text 2 | 3 | 4 | def test_migrate_up_to_specific_revision(alembic_runner, alembic_engine): 5 | alembic_runner.migrate_up_to("aaaaaaaaaaaa") 6 | 7 | with alembic_engine.begin() as conn: 8 | conn.execute(text("INSERT INTO foo (id) VALUES (100)")) 9 | 10 | alembic_runner.migrate_up_to("heads") 11 | 12 | with alembic_engine.connect() as conn: 13 | result = conn.execute(text("SELECT * FROM foo")).fetchall() 14 | assert len(result) == 1 15 | 16 | result = conn.execute(text("SELECT * FROM bar")).fetchall() 17 | assert len(result) == 0 18 | -------------------------------------------------------------------------------- /examples/test_branched_history_before_upgrade_data/alembic.ini: -------------------------------------------------------------------------------- 1 | [alembic] 2 | script_location = migrations 3 | 4 | [loggers] 5 | keys = root,sqlalchemy,alembic 6 | 7 | [handlers] 8 | keys = console 9 | 10 | [formatters] 11 | keys = generic 12 | 13 | [logger_root] 14 | level = WARN 15 | handlers = console 16 | qualname = 17 | 18 | [logger_sqlalchemy] 19 | level = WARN 20 | handlers = 21 | qualname = sqlalchemy.engine 22 | 23 | [logger_alembic] 24 | level = WARN 25 | handlers = 26 | qualname = alembic 27 | 28 | [handler_console] 29 | class = StreamHandler 30 | args = (sys.stderr,) 31 | level = NOTSET 32 | formatter = generic 33 | 34 | [formatter_generic] 35 | format = %(levelname)-5.5s [%(name)s] %(message)s 36 | datefmt = %H:%M:%S 37 | -------------------------------------------------------------------------------- /examples/test_branched_history_before_upgrade_data/conftest.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | from pytest_mock_resources import create_postgres_fixture 3 | 4 | alembic_engine = create_postgres_fixture() 5 | 6 | 7 | @pytest.fixture() 8 | def alembic_config(): 9 | return {"before_revision_data": {"bbbbbbbbbbbb": {"__tablename__": "foo", "id": 1}}} 10 | -------------------------------------------------------------------------------- /examples/test_branched_history_before_upgrade_data/migrations/env.py: -------------------------------------------------------------------------------- 1 | from alembic import context 2 | from models import Base 3 | from sqlalchemy import engine_from_config, pool 4 | 5 | target_metadata = Base.metadata 6 | 7 | 8 | connectable = context.config.attributes.get("connection", None) 9 | 10 | if connectable is None: 11 | connectable = engine_from_config( 12 | context.config.get_section(context.config.config_ini_section), 13 | prefix="sqlalchemy.", 14 | poolclass=pool.NullPool, 15 | ) 16 | 17 | with connectable.connect() as connection: 18 | context.configure(connection=connection, target_metadata=target_metadata) 19 | 20 | with context.begin_transaction(): 21 | context.run_migrations() 22 | -------------------------------------------------------------------------------- /examples/test_branched_history_before_upgrade_data/migrations/script.py.mako: -------------------------------------------------------------------------------- 1 | """${message} 2 | 3 | Revision ID: ${up_revision} 4 | Revises: ${down_revision | comma,n} 5 | Create Date: ${create_date} 6 | 7 | """ 8 | from alembic import op 9 | import sqlalchemy as sa 10 | ${imports if imports else ""} 11 | 12 | # revision identifiers, used by Alembic. 13 | revision = ${repr(up_revision)} 14 | down_revision = ${repr(down_revision)} 15 | branch_labels = ${repr(branch_labels)} 16 | depends_on = ${repr(depends_on)} 17 | 18 | 19 | def upgrade(): 20 | ${upgrades if upgrades else "pass"} 21 | 22 | 23 | def downgrade(): 24 | ${downgrades if downgrades else "pass"} 25 | -------------------------------------------------------------------------------- /examples/test_branched_history_before_upgrade_data/migrations/versions/70da13da0332_.py: -------------------------------------------------------------------------------- 1 | """empty message. 2 | 3 | Revision ID: 70da13da0332 4 | Revises: bbbbbbbbbbbb, cccccccccccc 5 | Create Date: 2021-05-07 08:56:12.886096 6 | 7 | """ 8 | 9 | 10 | # revision identifiers, used by Alembic. 11 | revision = "70da13da0332" 12 | down_revision = ("bbbbbbbbbbbb", "cccccccccccc") 13 | branch_labels = None 14 | depends_on = None 15 | 16 | 17 | def upgrade(): 18 | pass 19 | 20 | 21 | def downgrade(): 22 | pass 23 | -------------------------------------------------------------------------------- /examples/test_branched_history_before_upgrade_data/migrations/versions/aaaaaaaaaaaa_create_foo.py: -------------------------------------------------------------------------------- 1 | import sqlalchemy as sa 2 | from alembic import op 3 | 4 | revision = "aaaaaaaaaaaa" 5 | down_revision = None 6 | branch_labels = None 7 | depends_on = None 8 | 9 | 10 | def upgrade(): 11 | op.create_table( 12 | "foo", 13 | sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), 14 | sa.PrimaryKeyConstraint("id"), 15 | ) 16 | 17 | 18 | def downgrade(): 19 | op.drop_table("foo") 20 | -------------------------------------------------------------------------------- /examples/test_branched_history_before_upgrade_data/migrations/versions/bbbbbbbbbbbb_update_foo.py: -------------------------------------------------------------------------------- 1 | import sqlalchemy as sa 2 | from alembic import op 3 | 4 | revision = "bbbbbbbbbbbb" 5 | down_revision = "aaaaaaaaaaaa" 6 | branch_labels = None 7 | depends_on = None 8 | 9 | 10 | def upgrade(): 11 | op.add_column( 12 | "foo", 13 | sa.Column( 14 | "created_at", 15 | sa.DateTime(timezone=True), 16 | server_default=sa.text("'2020-01-01'"), 17 | nullable=False, 18 | ), 19 | ) 20 | 21 | 22 | def downgrade(): 23 | pass 24 | -------------------------------------------------------------------------------- /examples/test_branched_history_before_upgrade_data/migrations/versions/cccccccccccc_create_bar.py: -------------------------------------------------------------------------------- 1 | import sqlalchemy as sa 2 | from alembic import op 3 | 4 | revision = "cccccccccccc" 5 | down_revision = "aaaaaaaaaaaa" 6 | branch_labels = None 7 | depends_on = None 8 | 9 | 10 | def upgrade(): 11 | op.create_table( 12 | "bar", 13 | sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), 14 | sa.PrimaryKeyConstraint("id"), 15 | ) 16 | 17 | 18 | def downgrade(): 19 | op.drop_table("bar") 20 | -------------------------------------------------------------------------------- /examples/test_branched_history_before_upgrade_data/models.py: -------------------------------------------------------------------------------- 1 | import sqlalchemy 2 | from sqlalchemy import Column, types 3 | 4 | try: 5 | from sqlalchemy.orm import declarative_base 6 | except ImportError: 7 | from sqlalchemy.ext.declarative import declarative_base 8 | 9 | 10 | Base = declarative_base() 11 | 12 | 13 | class CreatedAt(Base): 14 | __tablename__ = "foo" 15 | 16 | id = Column(types.Integer(), autoincrement=True, primary_key=True) 17 | 18 | created_at = sqlalchemy.Column( 19 | sqlalchemy.types.DateTime(timezone=True), 20 | server_default=sqlalchemy.text("'2020-01-01'"), 21 | nullable=False, 22 | ) 23 | 24 | 25 | class Bar(Base): 26 | __tablename__ = "bar" 27 | 28 | id = Column(types.Integer(), autoincrement=True, primary_key=True) 29 | -------------------------------------------------------------------------------- /examples/test_branched_history_with_mergepoint/alembic.ini: -------------------------------------------------------------------------------- 1 | [alembic] 2 | script_location = migrations 3 | 4 | [loggers] 5 | keys = root,sqlalchemy,alembic 6 | 7 | [handlers] 8 | keys = console 9 | 10 | [formatters] 11 | keys = generic 12 | 13 | [logger_root] 14 | level = WARN 15 | handlers = console 16 | qualname = 17 | 18 | [logger_sqlalchemy] 19 | level = WARN 20 | handlers = 21 | qualname = sqlalchemy.engine 22 | 23 | [logger_alembic] 24 | level = INFO 25 | handlers = 26 | qualname = alembic 27 | 28 | [handler_console] 29 | class = StreamHandler 30 | args = (sys.stderr,) 31 | level = NOTSET 32 | formatter = generic 33 | 34 | [formatter_generic] 35 | format = %(levelname)-5.5s [%(name)s] %(message)s 36 | datefmt = %H:%M:%S 37 | -------------------------------------------------------------------------------- /examples/test_branched_history_with_mergepoint/conftest.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schireson/pytest-alembic/47748802f22db988fb95926189eb78ec59ad387f/examples/test_branched_history_with_mergepoint/conftest.py -------------------------------------------------------------------------------- /examples/test_branched_history_with_mergepoint/migrations/env.py: -------------------------------------------------------------------------------- 1 | from logging.config import fileConfig 2 | 3 | from alembic import context 4 | from models import Base 5 | from sqlalchemy import engine_from_config, pool 6 | 7 | fileConfig(context.config.config_file_name) 8 | target_metadata = Base.metadata 9 | 10 | 11 | connectable = context.config.attributes.get("connection", None) 12 | 13 | if connectable is None: 14 | connectable = engine_from_config( 15 | context.config.get_section(context.config.config_ini_section), 16 | prefix="sqlalchemy.", 17 | poolclass=pool.NullPool, 18 | ) 19 | 20 | with connectable.connect() as connection: 21 | context.configure(connection=connection, target_metadata=target_metadata) 22 | 23 | with context.begin_transaction(): 24 | context.run_migrations() 25 | -------------------------------------------------------------------------------- /examples/test_branched_history_with_mergepoint/migrations/script.py.mako: -------------------------------------------------------------------------------- 1 | """${message} 2 | 3 | Revision ID: ${up_revision} 4 | Revises: ${down_revision | comma,n} 5 | Create Date: ${create_date} 6 | 7 | """ 8 | from alembic import op 9 | import sqlalchemy as sa 10 | ${imports if imports else ""} 11 | 12 | # revision identifiers, used by Alembic. 13 | revision = ${repr(up_revision)} 14 | down_revision = ${repr(down_revision)} 15 | branch_labels = ${repr(branch_labels)} 16 | depends_on = ${repr(depends_on)} 17 | 18 | 19 | def upgrade(): 20 | ${upgrades if upgrades else "pass"} 21 | 22 | 23 | def downgrade(): 24 | ${downgrades if downgrades else "pass"} 25 | -------------------------------------------------------------------------------- /examples/test_branched_history_with_mergepoint/migrations/versions/70da13da0332_.py: -------------------------------------------------------------------------------- 1 | """empty message. 2 | 3 | Revision ID: 70da13da0332 4 | Revises: bbbbbbbbbbbb, cccccccccccc 5 | Create Date: 2021-05-07 08:56:12.886096 6 | 7 | """ 8 | 9 | 10 | # revision identifiers, used by Alembic. 11 | revision = "70da13da0332" 12 | down_revision = ("bbbbbbbbbbbb", "cccccccccccc") 13 | branch_labels = None 14 | depends_on = None 15 | 16 | 17 | def upgrade(): 18 | pass 19 | 20 | 21 | def downgrade(): 22 | pass 23 | -------------------------------------------------------------------------------- /examples/test_branched_history_with_mergepoint/migrations/versions/aaaaaaaaaaaa_create_foo.py: -------------------------------------------------------------------------------- 1 | import sqlalchemy as sa 2 | from alembic import op 3 | 4 | revision = "aaaaaaaaaaaa" 5 | down_revision = None 6 | branch_labels = None 7 | depends_on = None 8 | 9 | 10 | def upgrade(): 11 | op.create_table( 12 | "foo", 13 | sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), 14 | sa.PrimaryKeyConstraint("id"), 15 | ) 16 | 17 | 18 | def downgrade(): 19 | op.drop_table("foo") 20 | -------------------------------------------------------------------------------- /examples/test_branched_history_with_mergepoint/migrations/versions/bbbbbbbbbbbb_update_foo.py: -------------------------------------------------------------------------------- 1 | import sqlalchemy as sa 2 | from alembic import op 3 | 4 | revision = "bbbbbbbbbbbb" 5 | down_revision = "aaaaaaaaaaaa" 6 | branch_labels = None 7 | depends_on = None 8 | 9 | 10 | def upgrade(): 11 | op.add_column( 12 | "foo", 13 | sa.Column( 14 | "created_at", 15 | sa.DateTime(timezone=True), 16 | server_default=sa.text("'2020-01-01'"), 17 | nullable=False, 18 | ), 19 | ) 20 | 21 | 22 | def downgrade(): 23 | pass 24 | -------------------------------------------------------------------------------- /examples/test_branched_history_with_mergepoint/migrations/versions/cccccccccccc_create_bar.py: -------------------------------------------------------------------------------- 1 | import sqlalchemy as sa 2 | from alembic import op 3 | 4 | revision = "cccccccccccc" 5 | down_revision = "aaaaaaaaaaaa" 6 | branch_labels = None 7 | depends_on = None 8 | 9 | 10 | def upgrade(): 11 | op.create_table( 12 | "bar", 13 | sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), 14 | sa.PrimaryKeyConstraint("id"), 15 | ) 16 | 17 | 18 | def downgrade(): 19 | op.drop_table("bar") 20 | -------------------------------------------------------------------------------- /examples/test_branched_history_with_mergepoint/models.py: -------------------------------------------------------------------------------- 1 | import sqlalchemy 2 | from sqlalchemy import Column, types 3 | 4 | try: 5 | from sqlalchemy.orm import declarative_base 6 | except ImportError: 7 | from sqlalchemy.ext.declarative import declarative_base 8 | 9 | 10 | Base = declarative_base() 11 | 12 | 13 | class CreatedAt(Base): 14 | __tablename__ = "foo" 15 | 16 | id = Column(types.Integer(), autoincrement=True, primary_key=True) 17 | 18 | created_at = sqlalchemy.Column( 19 | sqlalchemy.types.DateTime(timezone=True), 20 | server_default=sqlalchemy.text("'2020-01-01'"), 21 | nullable=False, 22 | ) 23 | 24 | 25 | class Bar(Base): 26 | __tablename__ = "bar" 27 | 28 | id = Column(types.Integer(), autoincrement=True, primary_key=True) 29 | -------------------------------------------------------------------------------- /examples/test_branched_history_with_mergepoint/test_migrations.py: -------------------------------------------------------------------------------- 1 | from sqlalchemy import text 2 | 3 | 4 | def test_migrate_up_to_specific_revision(alembic_runner, alembic_engine): 5 | alembic_runner.migrate_up_to("aaaaaaaaaaaa") 6 | 7 | with alembic_engine.begin() as conn: 8 | conn.execute(text("INSERT INTO foo (id) VALUES (100)")) 9 | 10 | alembic_runner.migrate_up_to("head") 11 | 12 | with alembic_engine.connect() as conn: 13 | result = conn.execute(text("SELECT * FROM foo")).fetchall() 14 | assert len(result) == 1 15 | 16 | result = conn.execute(text("SELECT * FROM bar")).fetchall() 17 | assert len(result) == 0 18 | -------------------------------------------------------------------------------- /examples/test_complex_revision_upgrade_data/alembic.ini: -------------------------------------------------------------------------------- 1 | [alembic] 2 | script_location = migrations 3 | 4 | [loggers] 5 | keys = root,sqlalchemy,alembic 6 | 7 | [handlers] 8 | keys = console 9 | 10 | [formatters] 11 | keys = generic 12 | 13 | [logger_root] 14 | level = WARN 15 | handlers = console 16 | qualname = 17 | 18 | [logger_sqlalchemy] 19 | level = WARN 20 | handlers = 21 | qualname = sqlalchemy.engine 22 | 23 | [logger_alembic] 24 | level = INFO 25 | handlers = 26 | qualname = alembic 27 | 28 | [handler_console] 29 | class = StreamHandler 30 | args = (sys.stderr,) 31 | level = NOTSET 32 | formatter = generic 33 | 34 | [formatter_generic] 35 | format = %(levelname)-5.5s [%(name)s] %(message)s 36 | datefmt = %H:%M:%S 37 | -------------------------------------------------------------------------------- /examples/test_complex_revision_upgrade_data/conftest.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | from pytest_mock_resources import create_postgres_fixture 3 | 4 | alembic_engine = create_postgres_fixture() 5 | 6 | 7 | @pytest.fixture() 8 | def alembic_config(): 9 | return { 10 | "before_revision_data": { 11 | "bbbbbbbbbbbb": [ 12 | {"__tablename__": "foo", "id": 9}, 13 | {"__tablename__": "foo", "id": 10}, 14 | {"__tablename__": "bar", "id": 1}, 15 | ], 16 | "cccccccccccc": [{"__tablename__": "bar", "id": 2, "foo_id": 10}], 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /examples/test_complex_revision_upgrade_data/migrations/env.py: -------------------------------------------------------------------------------- 1 | from logging.config import fileConfig 2 | 3 | from alembic import context 4 | from models import Base 5 | from sqlalchemy import engine_from_config, pool 6 | 7 | fileConfig(context.config.config_file_name) 8 | target_metadata = Base.metadata 9 | 10 | 11 | connectable = context.config.attributes.get("connection", None) 12 | 13 | if connectable is None: 14 | connectable = engine_from_config( 15 | context.config.get_section(context.config.config_ini_section), 16 | prefix="sqlalchemy.", 17 | poolclass=pool.NullPool, 18 | ) 19 | 20 | with connectable.connect() as connection: 21 | context.configure(connection=connection, target_metadata=target_metadata) 22 | 23 | with context.begin_transaction(): 24 | context.run_migrations() 25 | -------------------------------------------------------------------------------- /examples/test_complex_revision_upgrade_data/migrations/script.py.mako: -------------------------------------------------------------------------------- 1 | """${message} 2 | 3 | Revision ID: ${up_revision} 4 | Revises: ${down_revision | comma,n} 5 | Create Date: ${create_date} 6 | 7 | """ 8 | from alembic import op 9 | import sqlalchemy as sa 10 | ${imports if imports else ""} 11 | 12 | # revision identifiers, used by Alembic. 13 | revision = ${repr(up_revision)} 14 | down_revision = ${repr(down_revision)} 15 | branch_labels = ${repr(branch_labels)} 16 | depends_on = ${repr(depends_on)} 17 | 18 | 19 | def upgrade(): 20 | ${upgrades if upgrades else "pass"} 21 | 22 | 23 | def downgrade(): 24 | ${downgrades if downgrades else "pass"} 25 | -------------------------------------------------------------------------------- /examples/test_complex_revision_upgrade_data/migrations/versions/aaaaaaaaaaaa_create_foo.py: -------------------------------------------------------------------------------- 1 | import sqlalchemy as sa 2 | from alembic import op 3 | 4 | revision = "aaaaaaaaaaaa" 5 | down_revision = None 6 | branch_labels = None 7 | depends_on = None 8 | 9 | 10 | def upgrade(): 11 | op.create_table( 12 | "foo", 13 | sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), 14 | sa.Column( 15 | "created_at", 16 | sa.DateTime(timezone=True), 17 | server_default=sa.text("(CURRENT_TIMESTAMP)"), 18 | nullable=False, 19 | ), 20 | sa.PrimaryKeyConstraint("id"), 21 | ) 22 | 23 | op.create_table( 24 | "bar", 25 | sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), 26 | ) 27 | 28 | 29 | def downgrade(): 30 | op.drop_table("bar") 31 | op.drop_table("foo") 32 | -------------------------------------------------------------------------------- /examples/test_complex_revision_upgrade_data/migrations/versions/bbbbbbbbbbbb_update_foo.py: -------------------------------------------------------------------------------- 1 | import sqlalchemy as sa 2 | from alembic import op 3 | 4 | revision = "bbbbbbbbbbbb" 5 | down_revision = "aaaaaaaaaaaa" 6 | branch_labels = None 7 | depends_on = None 8 | 9 | 10 | def upgrade(): 11 | op.add_column("bar", sa.Column("foo_id", sa.Integer(), server_default="9")) 12 | op.alter_column("bar", "foo_id", server_default=None, nullable=False) 13 | 14 | 15 | def downgrade(): 16 | pass 17 | -------------------------------------------------------------------------------- /examples/test_complex_revision_upgrade_data/migrations/versions/cccccccccccc_update_foo.py: -------------------------------------------------------------------------------- 1 | from alembic import op 2 | from sqlalchemy import text 3 | 4 | revision = "cccccccccccc" 5 | down_revision = "bbbbbbbbbbbb" 6 | branch_labels = None 7 | depends_on = None 8 | 9 | 10 | def upgrade(): 11 | conn = op.get_bind() 12 | result = conn.execute(text("SELECT * FROM foo")).fetchall() 13 | assert len(result) == 2 14 | assert result[0].id == 9, f"{result[0].id} == 9" 15 | assert result[1].id == 10, f"{result[1].id} == 10" 16 | 17 | result = conn.execute(text("SELECT * FROM bar")).fetchall() 18 | assert len(result) == 2 19 | assert result[0].id == 1, f"{result[0].id} == 1" 20 | assert result[0].foo_id == 9, f"{result[0].foo_id} == 9" 21 | assert result[1].id == 2, f"{result[1].id} == 2" 22 | assert result[1].foo_id == 10, f"{result[1].foo_id} == 10" 23 | 24 | 25 | def downgrade(): 26 | pass 27 | -------------------------------------------------------------------------------- /examples/test_complex_revision_upgrade_data/models.py: -------------------------------------------------------------------------------- 1 | import sqlalchemy 2 | from sqlalchemy import Column, types 3 | 4 | try: 5 | from sqlalchemy.orm import declarative_base 6 | except ImportError: 7 | from sqlalchemy.ext.declarative import declarative_base 8 | 9 | 10 | Base = declarative_base() 11 | 12 | 13 | class Foo(Base): 14 | __tablename__ = "foo" 15 | 16 | id = Column(types.Integer(), autoincrement=True, primary_key=True) 17 | 18 | created_at = sqlalchemy.Column( 19 | sqlalchemy.types.DateTime(timezone=True), 20 | server_default=sqlalchemy.text("CURRENT_TIMESTAMP"), 21 | nullable=False, 22 | ) 23 | 24 | 25 | class Bar(Base): 26 | __tablename__ = "bar" 27 | 28 | id = Column(types.Integer(), autoincrement=True, primary_key=True) 29 | foo_id = Column(types.Integer(), nullable=False) 30 | -------------------------------------------------------------------------------- /examples/test_consistency_doesnt_roundtrip/alembic.ini: -------------------------------------------------------------------------------- 1 | [alembic] 2 | script_location = migrations 3 | 4 | [loggers] 5 | keys = root,sqlalchemy,alembic 6 | 7 | [handlers] 8 | keys = console 9 | 10 | [formatters] 11 | keys = generic 12 | 13 | [logger_root] 14 | level = WARN 15 | handlers = console 16 | qualname = 17 | 18 | [logger_sqlalchemy] 19 | level = WARN 20 | handlers = 21 | qualname = sqlalchemy.engine 22 | 23 | [logger_alembic] 24 | level = INFO 25 | handlers = 26 | qualname = alembic 27 | 28 | [handler_console] 29 | class = StreamHandler 30 | args = (sys.stderr,) 31 | level = NOTSET 32 | formatter = generic 33 | 34 | [formatter_generic] 35 | format = %(levelname)-5.5s [%(name)s] %(message)s 36 | datefmt = %H:%M:%S 37 | -------------------------------------------------------------------------------- /examples/test_consistency_doesnt_roundtrip/conftest.py: -------------------------------------------------------------------------------- 1 | from pytest_mock_resources import create_postgres_fixture 2 | 3 | alembic_engine = create_postgres_fixture() 4 | -------------------------------------------------------------------------------- /examples/test_consistency_doesnt_roundtrip/migrations/env.py: -------------------------------------------------------------------------------- 1 | from logging.config import fileConfig 2 | 3 | from alembic import context 4 | from models import Base 5 | from sqlalchemy import engine_from_config, pool 6 | 7 | fileConfig(context.config.config_file_name) 8 | target_metadata = Base.metadata 9 | 10 | 11 | connectable = context.config.attributes.get("connection", None) 12 | 13 | if connectable is None: 14 | connectable = engine_from_config( 15 | context.config.get_section(context.config.config_ini_section), 16 | prefix="sqlalchemy.", 17 | poolclass=pool.NullPool, 18 | ) 19 | 20 | with connectable.connect() as connection: 21 | context.configure(connection=connection, target_metadata=target_metadata) 22 | 23 | with context.begin_transaction(): 24 | context.run_migrations() 25 | -------------------------------------------------------------------------------- /examples/test_consistency_doesnt_roundtrip/migrations/script.py.mako: -------------------------------------------------------------------------------- 1 | """${message} 2 | 3 | Revision ID: ${up_revision} 4 | Revises: ${down_revision | comma,n} 5 | Create Date: ${create_date} 6 | 7 | """ 8 | from alembic import op 9 | import sqlalchemy as sa 10 | ${imports if imports else ""} 11 | 12 | # revision identifiers, used by Alembic. 13 | revision = ${repr(up_revision)} 14 | down_revision = ${repr(down_revision)} 15 | branch_labels = ${repr(branch_labels)} 16 | depends_on = ${repr(depends_on)} 17 | 18 | 19 | def upgrade(): 20 | ${upgrades if upgrades else "pass"} 21 | 22 | 23 | def downgrade(): 24 | ${downgrades if downgrades else "pass"} 25 | -------------------------------------------------------------------------------- /examples/test_consistency_doesnt_roundtrip/migrations/versions/aaaaaaaaaaaa_create_foo.py: -------------------------------------------------------------------------------- 1 | import sqlalchemy as sa 2 | from alembic import op 3 | 4 | revision = "aaaaaaaaaaaa" 5 | down_revision = None 6 | branch_labels = None 7 | depends_on = None 8 | 9 | 10 | def upgrade(): 11 | op.create_table( 12 | "foo", 13 | sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), 14 | sa.PrimaryKeyConstraint("id"), 15 | ) 16 | 17 | 18 | def downgrade(): 19 | pass 20 | -------------------------------------------------------------------------------- /examples/test_consistency_doesnt_roundtrip/models.py: -------------------------------------------------------------------------------- 1 | from sqlalchemy import Column, types 2 | 3 | try: 4 | from sqlalchemy.orm import declarative_base 5 | except ImportError: 6 | from sqlalchemy.ext.declarative import declarative_base 7 | 8 | 9 | Base = declarative_base() 10 | 11 | 12 | class CreatedAt(Base): 13 | __tablename__ = "foo" 14 | 15 | id = Column(types.Integer(), autoincrement=True, primary_key=True) 16 | -------------------------------------------------------------------------------- /examples/test_default_env_script/alembic.ini: -------------------------------------------------------------------------------- 1 | [alembic] 2 | script_location = migrations 3 | 4 | [loggers] 5 | keys = root,sqlalchemy,alembic 6 | 7 | [handlers] 8 | keys = console 9 | 10 | [formatters] 11 | keys = generic 12 | 13 | [logger_root] 14 | level = WARN 15 | handlers = console 16 | qualname = 17 | 18 | [logger_sqlalchemy] 19 | level = WARN 20 | handlers = 21 | qualname = sqlalchemy.engine 22 | 23 | [logger_alembic] 24 | level = INFO 25 | handlers = 26 | qualname = alembic 27 | 28 | [handler_console] 29 | class = StreamHandler 30 | args = (sys.stderr,) 31 | level = NOTSET 32 | formatter = generic 33 | 34 | [formatter_generic] 35 | format = %(levelname)-5.5s [%(name)s] %(message)s 36 | datefmt = %H:%M:%S 37 | -------------------------------------------------------------------------------- /examples/test_default_env_script/conftest.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schireson/pytest-alembic/47748802f22db988fb95926189eb78ec59ad387f/examples/test_default_env_script/conftest.py -------------------------------------------------------------------------------- /examples/test_default_env_script/migrations/script.py.mako: -------------------------------------------------------------------------------- 1 | """${message} 2 | 3 | Revision ID: ${up_revision} 4 | Revises: ${down_revision | comma,n} 5 | Create Date: ${create_date} 6 | 7 | """ 8 | from alembic import op 9 | import sqlalchemy as sa 10 | ${imports if imports else ""} 11 | 12 | # revision identifiers, used by Alembic. 13 | revision = ${repr(up_revision)} 14 | down_revision = ${repr(down_revision)} 15 | branch_labels = ${repr(branch_labels)} 16 | depends_on = ${repr(depends_on)} 17 | 18 | 19 | def upgrade(): 20 | ${upgrades if upgrades else "pass"} 21 | 22 | 23 | def downgrade(): 24 | ${downgrades if downgrades else "pass"} 25 | -------------------------------------------------------------------------------- /examples/test_default_env_script/migrations/versions/aaaaaaaaaaaa_create_foo.py: -------------------------------------------------------------------------------- 1 | import sqlalchemy as sa 2 | from alembic import op 3 | 4 | revision = "aaaaaaaaaaaa" 5 | down_revision = None 6 | branch_labels = None 7 | depends_on = None 8 | 9 | 10 | def upgrade(): 11 | op.create_table( 12 | "foo", 13 | sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), 14 | sa.Column( 15 | "created_at", 16 | sa.DateTime(timezone=True), 17 | server_default=sa.text("(CURRENT_TIMESTAMP)"), 18 | nullable=False, 19 | ), 20 | sa.PrimaryKeyConstraint("id"), 21 | ) 22 | 23 | 24 | def downgrade(): 25 | op.drop_table("foo") 26 | -------------------------------------------------------------------------------- /examples/test_default_env_script/migrations/versions/bbbbbbbbbbbb_update_foo.py: -------------------------------------------------------------------------------- 1 | from alembic import op 2 | 3 | revision = "bbbbbbbbbbbb" 4 | down_revision = "aaaaaaaaaaaa" 5 | branch_labels = None 6 | depends_on = None 7 | 8 | 9 | def upgrade(): 10 | conn = op.get_bind() 11 | result = conn.execute("SELECT * FROM foo").fetchall() 12 | assert len(result) == 0 13 | 14 | 15 | def downgrade(): 16 | pass 17 | -------------------------------------------------------------------------------- /examples/test_default_env_script/models.py: -------------------------------------------------------------------------------- 1 | import sqlalchemy 2 | from sqlalchemy import Column, types 3 | 4 | try: 5 | from sqlalchemy.orm import declarative_base 6 | except ImportError: 7 | from sqlalchemy.ext.declarative import declarative_base 8 | 9 | 10 | Base = declarative_base() 11 | 12 | 13 | class CreatedAt(Base): 14 | __tablename__ = "foo" 15 | 16 | id = Column(types.Integer(), autoincrement=True, primary_key=True) 17 | 18 | created_at = sqlalchemy.Column( 19 | sqlalchemy.types.DateTime(timezone=True), 20 | server_default=sqlalchemy.text("CURRENT_TIMESTAMP"), 21 | nullable=False, 22 | ) 23 | -------------------------------------------------------------------------------- /examples/test_default_script_location/alembic.ini: -------------------------------------------------------------------------------- 1 | [alembic] 2 | 3 | [loggers] 4 | keys = root,sqlalchemy,alembic 5 | 6 | [handlers] 7 | keys = console 8 | 9 | [formatters] 10 | keys = generic 11 | 12 | [logger_root] 13 | level = WARN 14 | handlers = console 15 | qualname = 16 | 17 | [logger_sqlalchemy] 18 | level = WARN 19 | handlers = 20 | qualname = sqlalchemy.engine 21 | 22 | [logger_alembic] 23 | level = INFO 24 | handlers = 25 | qualname = alembic 26 | 27 | [handler_console] 28 | class = StreamHandler 29 | args = (sys.stderr,) 30 | level = NOTSET 31 | formatter = generic 32 | 33 | [formatter_generic] 34 | format = %(levelname)-5.5s [%(name)s] %(message)s 35 | datefmt = %H:%M:%S 36 | -------------------------------------------------------------------------------- /examples/test_default_script_location/conftest.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schireson/pytest-alembic/47748802f22db988fb95926189eb78ec59ad387f/examples/test_default_script_location/conftest.py -------------------------------------------------------------------------------- /examples/test_default_script_location/migrations/env.py: -------------------------------------------------------------------------------- 1 | from logging.config import fileConfig 2 | 3 | from alembic import context 4 | from models import Base 5 | from sqlalchemy import engine_from_config, pool 6 | 7 | fileConfig(context.config.config_file_name) 8 | target_metadata = Base.metadata 9 | 10 | 11 | connectable = context.config.attributes.get("connection", None) 12 | 13 | if connectable is None: 14 | connectable = engine_from_config( 15 | context.config.get_section(context.config.config_ini_section), 16 | prefix="sqlalchemy.", 17 | poolclass=pool.NullPool, 18 | ) 19 | 20 | with connectable.connect() as connection: 21 | context.configure(connection=connection, target_metadata=target_metadata) 22 | 23 | with context.begin_transaction(): 24 | context.run_migrations() 25 | -------------------------------------------------------------------------------- /examples/test_default_script_location/migrations/script.py.mako: -------------------------------------------------------------------------------- 1 | """${message} 2 | 3 | Revision ID: ${up_revision} 4 | Revises: ${down_revision | comma,n} 5 | Create Date: ${create_date} 6 | 7 | """ 8 | from alembic import op 9 | import sqlalchemy as sa 10 | ${imports if imports else ""} 11 | 12 | # revision identifiers, used by Alembic. 13 | revision = ${repr(up_revision)} 14 | down_revision = ${repr(down_revision)} 15 | branch_labels = ${repr(branch_labels)} 16 | depends_on = ${repr(depends_on)} 17 | 18 | 19 | def upgrade(): 20 | ${upgrades if upgrades else "pass"} 21 | 22 | 23 | def downgrade(): 24 | ${downgrades if downgrades else "pass"} 25 | -------------------------------------------------------------------------------- /examples/test_default_script_location/migrations/versions/aaaaaaaaaaaa_create_foo.py: -------------------------------------------------------------------------------- 1 | import sqlalchemy as sa 2 | from alembic import op 3 | 4 | revision = "aaaaaaaaaaaa" 5 | down_revision = None 6 | branch_labels = None 7 | depends_on = None 8 | 9 | 10 | def upgrade(): 11 | op.create_table( 12 | "foo", 13 | sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), 14 | sa.Column( 15 | "created_at", 16 | sa.DateTime(timezone=True), 17 | server_default=sa.text("(CURRENT_TIMESTAMP)"), 18 | nullable=False, 19 | ), 20 | sa.PrimaryKeyConstraint("id"), 21 | ) 22 | 23 | 24 | def downgrade(): 25 | op.drop_table("foo") 26 | -------------------------------------------------------------------------------- /examples/test_default_script_location/migrations/versions/bbbbbbbbbbbb_update_foo.py: -------------------------------------------------------------------------------- 1 | from alembic import op 2 | from sqlalchemy import text 3 | 4 | revision = "bbbbbbbbbbbb" 5 | down_revision = "aaaaaaaaaaaa" 6 | branch_labels = None 7 | depends_on = None 8 | 9 | 10 | def upgrade(): 11 | conn = op.get_bind() 12 | result = conn.execute(text("SELECT * FROM foo")).fetchall() 13 | assert len(result) == 0 14 | 15 | 16 | def downgrade(): 17 | pass 18 | -------------------------------------------------------------------------------- /examples/test_default_script_location/models.py: -------------------------------------------------------------------------------- 1 | import sqlalchemy 2 | from sqlalchemy import Column, types 3 | 4 | try: 5 | from sqlalchemy.orm import declarative_base 6 | except ImportError: 7 | from sqlalchemy.ext.declarative import declarative_base 8 | 9 | 10 | Base = declarative_base() 11 | 12 | 13 | class CreatedAt(Base): 14 | __tablename__ = "foo" 15 | 16 | id = Column(types.Integer(), autoincrement=True, primary_key=True) 17 | 18 | created_at = sqlalchemy.Column( 19 | sqlalchemy.types.DateTime(timezone=True), 20 | server_default=sqlalchemy.text("CURRENT_TIMESTAMP"), 21 | nullable=False, 22 | ) 23 | -------------------------------------------------------------------------------- /examples/test_downgrade_leaves_no_trace_failure/alembic.ini: -------------------------------------------------------------------------------- 1 | [alembic] 2 | script_location = migrations 3 | 4 | [loggers] 5 | keys = root,sqlalchemy,alembic 6 | 7 | [handlers] 8 | keys = console 9 | 10 | [formatters] 11 | keys = generic 12 | 13 | [logger_root] 14 | level = WARN 15 | handlers = console 16 | qualname = 17 | 18 | [logger_sqlalchemy] 19 | level = WARN 20 | handlers = 21 | qualname = sqlalchemy.engine 22 | 23 | [logger_alembic] 24 | level = INFO 25 | handlers = 26 | qualname = alembic 27 | 28 | [handler_console] 29 | class = StreamHandler 30 | args = (sys.stderr,) 31 | level = NOTSET 32 | formatter = generic 33 | 34 | [formatter_generic] 35 | format = %(levelname)-5.5s [%(name)s] %(message)s 36 | datefmt = %H:%M:%S 37 | -------------------------------------------------------------------------------- /examples/test_downgrade_leaves_no_trace_failure/conftest.py: -------------------------------------------------------------------------------- 1 | from pytest_mock_resources import create_postgres_fixture 2 | 3 | alembic_engine = create_postgres_fixture() 4 | -------------------------------------------------------------------------------- /examples/test_downgrade_leaves_no_trace_failure/migrations/env.py: -------------------------------------------------------------------------------- 1 | from logging.config import fileConfig 2 | 3 | from alembic import context 4 | from models import Base 5 | from sqlalchemy import engine_from_config, pool 6 | 7 | fileConfig(context.config.config_file_name) 8 | target_metadata = Base.metadata 9 | 10 | 11 | connectable = context.config.attributes.get("connection", None) 12 | 13 | if connectable is None: 14 | connectable = engine_from_config( 15 | context.config.get_section(context.config.config_ini_section), 16 | prefix="sqlalchemy.", 17 | poolclass=pool.NullPool, 18 | ) 19 | 20 | with connectable.connect() as connection: 21 | context.configure(connection=connection, target_metadata=target_metadata) 22 | 23 | with context.begin_transaction(): 24 | context.run_migrations() 25 | -------------------------------------------------------------------------------- /examples/test_downgrade_leaves_no_trace_failure/migrations/script.py.mako: -------------------------------------------------------------------------------- 1 | """${message} 2 | 3 | Revision ID: ${up_revision} 4 | Revises: ${down_revision | comma,n} 5 | Create Date: ${create_date} 6 | 7 | """ 8 | from alembic import op 9 | import sqlalchemy as sa 10 | ${imports if imports else ""} 11 | 12 | # revision identifiers, used by Alembic. 13 | revision = ${repr(up_revision)} 14 | down_revision = ${repr(down_revision)} 15 | branch_labels = ${repr(branch_labels)} 16 | depends_on = ${repr(depends_on)} 17 | 18 | 19 | def upgrade(): 20 | ${upgrades if upgrades else "pass"} 21 | 22 | 23 | def downgrade(): 24 | ${downgrades if downgrades else "pass"} 25 | -------------------------------------------------------------------------------- /examples/test_downgrade_leaves_no_trace_failure/migrations/versions/aaaaaaaaaaaa_create_foo.py: -------------------------------------------------------------------------------- 1 | import sqlalchemy as sa 2 | from alembic import op 3 | 4 | revision = "aaaaaaaaaaaa" 5 | down_revision = None 6 | branch_labels = None 7 | depends_on = None 8 | 9 | 10 | def upgrade(): 11 | op.create_table( 12 | "ignore", 13 | sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), 14 | sa.PrimaryKeyConstraint("id"), 15 | ) 16 | 17 | 18 | def downgrade(): 19 | op.drop_table("ignore") 20 | -------------------------------------------------------------------------------- /examples/test_downgrade_leaves_no_trace_failure/migrations/versions/bbbbbbbbbbbb_create_foo.py: -------------------------------------------------------------------------------- 1 | import sqlalchemy as sa 2 | from alembic import op 3 | 4 | revision = "bbbbbbbbbbbb" 5 | down_revision = "aaaaaaaaaaaa" 6 | branch_labels = None 7 | depends_on = None 8 | 9 | 10 | def upgrade(): 11 | op.create_table( 12 | "foo", 13 | sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), 14 | sa.PrimaryKeyConstraint("id"), 15 | ) 16 | 17 | 18 | def downgrade(): 19 | op.rename_table("foo", "bar") 20 | -------------------------------------------------------------------------------- /examples/test_downgrade_leaves_no_trace_failure/models.py: -------------------------------------------------------------------------------- 1 | from sqlalchemy import Column, types 2 | 3 | try: 4 | from sqlalchemy.orm import declarative_base 5 | except ImportError: 6 | from sqlalchemy.ext.declarative import declarative_base 7 | 8 | 9 | Base = declarative_base() 10 | 11 | 12 | class CreatedAt(Base): 13 | __tablename__ = "foo" 14 | 15 | id = Column(types.Integer(), autoincrement=True, primary_key=True) 16 | -------------------------------------------------------------------------------- /examples/test_downgrade_leaves_no_trace_failure/setup.cfg: -------------------------------------------------------------------------------- 1 | [tool:pytest] 2 | pytest_alembic_exclude = upgrade,single_head_revision,model_definitions_match_ddl,up_down_consistency 3 | pytest_alembic_include_experimental = downgrade_leaves_no_trace 4 | -------------------------------------------------------------------------------- /examples/test_downgrade_leaves_no_trace_success/alembic.ini: -------------------------------------------------------------------------------- 1 | [alembic] 2 | script_location = migrations 3 | 4 | [loggers] 5 | keys = root,sqlalchemy,alembic 6 | 7 | [handlers] 8 | keys = console 9 | 10 | [formatters] 11 | keys = generic 12 | 13 | [logger_root] 14 | level = WARN 15 | handlers = console 16 | qualname = 17 | 18 | [logger_sqlalchemy] 19 | level = WARN 20 | handlers = 21 | qualname = sqlalchemy.engine 22 | 23 | [logger_alembic] 24 | level = INFO 25 | handlers = 26 | qualname = alembic 27 | 28 | [handler_console] 29 | class = StreamHandler 30 | args = (sys.stderr,) 31 | level = NOTSET 32 | formatter = generic 33 | 34 | [formatter_generic] 35 | format = %(levelname)-5.5s [%(name)s] %(message)s 36 | datefmt = %H:%M:%S 37 | -------------------------------------------------------------------------------- /examples/test_downgrade_leaves_no_trace_success/conftest.py: -------------------------------------------------------------------------------- 1 | from pytest_mock_resources import create_postgres_fixture 2 | 3 | alembic_engine = create_postgres_fixture() 4 | -------------------------------------------------------------------------------- /examples/test_downgrade_leaves_no_trace_success/migrations/env.py: -------------------------------------------------------------------------------- 1 | from logging.config import fileConfig 2 | 3 | from alembic import context 4 | from models import Base 5 | from sqlalchemy import engine_from_config, pool 6 | 7 | fileConfig(context.config.config_file_name) 8 | target_metadata = Base.metadata 9 | 10 | 11 | connectable = context.config.attributes.get("connection", None) 12 | 13 | if connectable is None: 14 | connectable = engine_from_config( 15 | context.config.get_section(context.config.config_ini_section), 16 | prefix="sqlalchemy.", 17 | poolclass=pool.NullPool, 18 | ) 19 | 20 | with connectable.connect() as connection: 21 | context.configure(connection=connection, target_metadata=target_metadata) 22 | 23 | with context.begin_transaction(): 24 | context.run_migrations() 25 | -------------------------------------------------------------------------------- /examples/test_downgrade_leaves_no_trace_success/migrations/script.py.mako: -------------------------------------------------------------------------------- 1 | """${message} 2 | 3 | Revision ID: ${up_revision} 4 | Revises: ${down_revision | comma,n} 5 | Create Date: ${create_date} 6 | 7 | """ 8 | from alembic import op 9 | import sqlalchemy as sa 10 | ${imports if imports else ""} 11 | 12 | # revision identifiers, used by Alembic. 13 | revision = ${repr(up_revision)} 14 | down_revision = ${repr(down_revision)} 15 | branch_labels = ${repr(branch_labels)} 16 | depends_on = ${repr(depends_on)} 17 | 18 | 19 | def upgrade(): 20 | ${upgrades if upgrades else "pass"} 21 | 22 | 23 | def downgrade(): 24 | ${downgrades if downgrades else "pass"} 25 | -------------------------------------------------------------------------------- /examples/test_downgrade_leaves_no_trace_success/migrations/versions/aaaaaaaaaaaa_create_foo.py: -------------------------------------------------------------------------------- 1 | import sqlalchemy as sa 2 | from alembic import op 3 | 4 | revision = "aaaaaaaaaaaa" 5 | down_revision = None 6 | branch_labels = None 7 | depends_on = None 8 | 9 | 10 | def upgrade(): 11 | op.create_table( 12 | "foo", 13 | sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), 14 | sa.PrimaryKeyConstraint("id"), 15 | ) 16 | 17 | 18 | def downgrade(): 19 | op.drop_table("foo") 20 | -------------------------------------------------------------------------------- /examples/test_downgrade_leaves_no_trace_success/models.py: -------------------------------------------------------------------------------- 1 | from sqlalchemy import Column, types 2 | 3 | try: 4 | from sqlalchemy.orm import declarative_base 5 | except ImportError: 6 | from sqlalchemy.ext.declarative import declarative_base 7 | 8 | 9 | Base = declarative_base() 10 | 11 | 12 | class CreatedAt(Base): 13 | __tablename__ = "foo" 14 | 15 | id = Column(types.Integer(), autoincrement=True, primary_key=True) 16 | -------------------------------------------------------------------------------- /examples/test_downgrade_leaves_no_trace_success/setup.cfg: -------------------------------------------------------------------------------- 1 | [tool:pytest] 2 | pytest_alembic_include_experimental = downgrade_leaves_no_trace 3 | -------------------------------------------------------------------------------- /examples/test_empty_history/alembic.ini: -------------------------------------------------------------------------------- 1 | [alembic] 2 | script_location = migrations 3 | 4 | [loggers] 5 | keys = root,sqlalchemy,alembic 6 | 7 | [handlers] 8 | keys = console 9 | 10 | [formatters] 11 | keys = generic 12 | 13 | [logger_root] 14 | level = WARN 15 | handlers = console 16 | qualname = 17 | 18 | [logger_sqlalchemy] 19 | level = WARN 20 | handlers = 21 | qualname = sqlalchemy.engine 22 | 23 | [logger_alembic] 24 | level = INFO 25 | handlers = 26 | qualname = alembic 27 | 28 | [handler_console] 29 | class = StreamHandler 30 | args = (sys.stderr,) 31 | level = NOTSET 32 | formatter = generic 33 | 34 | [formatter_generic] 35 | format = %(levelname)-5.5s [%(name)s] %(message)s 36 | datefmt = %H:%M:%S 37 | -------------------------------------------------------------------------------- /examples/test_empty_history/conftest.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schireson/pytest-alembic/47748802f22db988fb95926189eb78ec59ad387f/examples/test_empty_history/conftest.py -------------------------------------------------------------------------------- /examples/test_empty_history/migrations/env.py: -------------------------------------------------------------------------------- 1 | from logging.config import fileConfig 2 | 3 | from alembic import context 4 | from models import Base 5 | from sqlalchemy import engine_from_config, pool 6 | 7 | fileConfig(context.config.config_file_name) 8 | target_metadata = Base.metadata 9 | 10 | 11 | connectable = context.config.attributes.get("connection", None) 12 | 13 | if connectable is None: 14 | connectable = engine_from_config( 15 | context.config.get_section(context.config.config_ini_section), 16 | prefix="sqlalchemy.", 17 | poolclass=pool.NullPool, 18 | ) 19 | 20 | with connectable.connect() as connection: 21 | context.configure(connection=connection, target_metadata=target_metadata) 22 | 23 | with context.begin_transaction(): 24 | context.run_migrations() 25 | -------------------------------------------------------------------------------- /examples/test_empty_history/migrations/script.py.mako: -------------------------------------------------------------------------------- 1 | """${message} 2 | 3 | Revision ID: ${up_revision} 4 | Revises: ${down_revision | comma,n} 5 | Create Date: ${create_date} 6 | 7 | """ 8 | from alembic import op 9 | import sqlalchemy as sa 10 | ${imports if imports else ""} 11 | 12 | # revision identifiers, used by Alembic. 13 | revision = ${repr(up_revision)} 14 | down_revision = ${repr(down_revision)} 15 | branch_labels = ${repr(branch_labels)} 16 | depends_on = ${repr(depends_on)} 17 | 18 | 19 | def upgrade(): 20 | ${upgrades if upgrades else "pass"} 21 | 22 | 23 | def downgrade(): 24 | ${downgrades if downgrades else "pass"} 25 | -------------------------------------------------------------------------------- /examples/test_empty_history/migrations/versions/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schireson/pytest-alembic/47748802f22db988fb95926189eb78ec59ad387f/examples/test_empty_history/migrations/versions/.gitkeep -------------------------------------------------------------------------------- /examples/test_empty_history/models.py: -------------------------------------------------------------------------------- 1 | try: 2 | from sqlalchemy.orm import declarative_base 3 | except ImportError: 4 | from sqlalchemy.ext.declarative import declarative_base 5 | 6 | 7 | Base = declarative_base() 8 | -------------------------------------------------------------------------------- /examples/test_empty_history/setup.cfg: -------------------------------------------------------------------------------- 1 | [tool:pytest] 2 | pytest_alembic_exclude = single_head_revision 3 | pytest_alembic_include_experimental = downgrade_leaves_no_trace,all_models_register_on_metadata 4 | -------------------------------------------------------------------------------- /examples/test_experimental_all_models_register/alembic.ini: -------------------------------------------------------------------------------- 1 | [alembic] 2 | script_location = migrations 3 | 4 | [loggers] 5 | keys = root,sqlalchemy,alembic 6 | 7 | [handlers] 8 | keys = console 9 | 10 | [formatters] 11 | keys = generic 12 | 13 | [logger_root] 14 | level = WARN 15 | handlers = console 16 | qualname = 17 | 18 | [logger_sqlalchemy] 19 | level = WARN 20 | handlers = 21 | qualname = sqlalchemy.engine 22 | 23 | [logger_alembic] 24 | level = INFO 25 | handlers = 26 | qualname = alembic 27 | 28 | [handler_console] 29 | class = StreamHandler 30 | args = (sys.stderr,) 31 | level = NOTSET 32 | formatter = generic 33 | 34 | [formatter_generic] 35 | format = %(levelname)-5.5s [%(name)s] %(message)s 36 | datefmt = %H:%M:%S 37 | -------------------------------------------------------------------------------- /examples/test_experimental_all_models_register/conftest.py: -------------------------------------------------------------------------------- 1 | import pytest_alembic.tests.experimental 2 | 3 | 4 | def test_all_models_register_on_metadata(alembic_runner): 5 | pytest_alembic.tests.experimental.test_all_models_register_on_metadata(alembic_runner, "models") 6 | -------------------------------------------------------------------------------- /examples/test_experimental_all_models_register/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schireson/pytest-alembic/47748802f22db988fb95926189eb78ec59ad387f/examples/test_experimental_all_models_register/migrations/__init__.py -------------------------------------------------------------------------------- /examples/test_experimental_all_models_register/migrations/env.py: -------------------------------------------------------------------------------- 1 | from logging.config import fileConfig 2 | 3 | from alembic import context 4 | from models import Base 5 | from sqlalchemy import engine_from_config, pool 6 | 7 | fileConfig(context.config.config_file_name) 8 | target_metadata = Base.metadata 9 | 10 | 11 | connectable = context.config.attributes.get("connection", None) 12 | 13 | if connectable is None: 14 | connectable = engine_from_config( 15 | context.config.get_section(context.config.config_ini_section), 16 | prefix="sqlalchemy.", 17 | poolclass=pool.NullPool, 18 | ) 19 | 20 | with connectable.connect() as connection: 21 | context.configure(connection=connection, target_metadata=target_metadata) 22 | 23 | with context.begin_transaction(): 24 | context.run_migrations() 25 | -------------------------------------------------------------------------------- /examples/test_experimental_all_models_register/migrations/script.py.mako: -------------------------------------------------------------------------------- 1 | """${message} 2 | 3 | Revision ID: ${up_revision} 4 | Revises: ${down_revision | comma,n} 5 | Create Date: ${create_date} 6 | 7 | """ 8 | from alembic import op 9 | import sqlalchemy as sa 10 | ${imports if imports else ""} 11 | 12 | # revision identifiers, used by Alembic. 13 | revision = ${repr(up_revision)} 14 | down_revision = ${repr(down_revision)} 15 | branch_labels = ${repr(branch_labels)} 16 | depends_on = ${repr(depends_on)} 17 | 18 | 19 | def upgrade(): 20 | ${upgrades if upgrades else "pass"} 21 | 22 | 23 | def downgrade(): 24 | ${downgrades if downgrades else "pass"} 25 | -------------------------------------------------------------------------------- /examples/test_experimental_all_models_register/migrations/versions/aaaaaaaaaaaa_create_foo.py: -------------------------------------------------------------------------------- 1 | import sqlalchemy as sa 2 | from alembic import op 3 | 4 | revision = "aaaaaaaaaaaa" 5 | down_revision = None 6 | branch_labels = None 7 | depends_on = None 8 | 9 | 10 | def upgrade(): 11 | op.create_table( 12 | "foo", 13 | sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), 14 | sa.Column( 15 | "created_at", 16 | sa.DateTime(timezone=True), 17 | server_default=sa.text("(CURRENT_TIMESTAMP)"), 18 | nullable=False, 19 | ), 20 | sa.PrimaryKeyConstraint("id"), 21 | ) 22 | 23 | 24 | def downgrade(): 25 | op.drop_table("foo") 26 | -------------------------------------------------------------------------------- /examples/test_experimental_all_models_register/migrations/versions/bbbbbbbbbbbb_update_foo.py: -------------------------------------------------------------------------------- 1 | from alembic import op 2 | from sqlalchemy import text 3 | 4 | revision = "bbbbbbbbbbbb" 5 | down_revision = "aaaaaaaaaaaa" 6 | branch_labels = None 7 | depends_on = None 8 | 9 | 10 | def upgrade(): 11 | conn = op.get_bind() 12 | result = conn.execute(text("SELECT * FROM foo")).fetchall() 13 | assert len(result) == 0 14 | 15 | 16 | def downgrade(): 17 | pass 18 | -------------------------------------------------------------------------------- /examples/test_experimental_all_models_register/models.py: -------------------------------------------------------------------------------- 1 | import sqlalchemy 2 | from sqlalchemy import Column, types 3 | 4 | try: 5 | from sqlalchemy.orm import declarative_base 6 | except ImportError: 7 | from sqlalchemy.ext.declarative import declarative_base 8 | 9 | 10 | Base = declarative_base() 11 | 12 | 13 | class CreatedAt(Base): 14 | __tablename__ = "foo" 15 | 16 | id = Column(types.Integer(), autoincrement=True, primary_key=True) 17 | 18 | created_at = sqlalchemy.Column( 19 | sqlalchemy.types.DateTime(timezone=True), 20 | server_default=sqlalchemy.text("CURRENT_TIMESTAMP"), 21 | nullable=False, 22 | ) 23 | -------------------------------------------------------------------------------- /examples/test_experimental_all_models_register_async/alembic.ini: -------------------------------------------------------------------------------- 1 | 2 | [alembic] 3 | script_location = migrations 4 | 5 | [loggers] 6 | keys = root,sqlalchemy,alembic 7 | 8 | [handlers] 9 | keys = console 10 | 11 | [formatters] 12 | keys = generic 13 | 14 | [logger_root] 15 | level = WARN 16 | handlers = console 17 | qualname = 18 | 19 | [logger_sqlalchemy] 20 | level = WARN 21 | handlers = 22 | qualname = sqlalchemy.engine 23 | 24 | [logger_alembic] 25 | level = INFO 26 | handlers = 27 | qualname = alembic 28 | 29 | [handler_console] 30 | class = StreamHandler 31 | args = (sys.stderr,) 32 | level = NOTSET 33 | formatter = generic 34 | 35 | [formatter_generic] 36 | format = %(levelname)-5.5s [%(name)s] %(message)s 37 | datefmt = %H:%M:%S 38 | -------------------------------------------------------------------------------- /examples/test_experimental_all_models_register_async/conftest.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | from pytest_mock_resources import create_postgres_fixture 3 | 4 | import pytest_alembic.tests.experimental 5 | 6 | alembic_engine = create_postgres_fixture(async_=True) 7 | 8 | 9 | @pytest.fixture() 10 | def alembic_config(): 11 | return {"before_revision_data": {"bbbbbbbbbbbb": {"__tablename__": "foo", "id": 9}}} 12 | 13 | 14 | def test_all_models_register_on_metadata(alembic_runner): 15 | pytest_alembic.tests.experimental.test_all_models_register_on_metadata( 16 | alembic_runner, "models", async_=True 17 | ) 18 | -------------------------------------------------------------------------------- /examples/test_experimental_all_models_register_async/migrations/script.py.mako: -------------------------------------------------------------------------------- 1 | """${message} 2 | 3 | Revision ID: ${up_revision} 4 | Revises: ${down_revision | comma,n} 5 | Create Date: ${create_date} 6 | 7 | """ 8 | from alembic import op 9 | import sqlalchemy as sa 10 | ${imports if imports else ""} 11 | 12 | # revision identifiers, used by Alembic. 13 | revision = ${repr(up_revision)} 14 | down_revision = ${repr(down_revision)} 15 | branch_labels = ${repr(branch_labels)} 16 | depends_on = ${repr(depends_on)} 17 | 18 | 19 | def upgrade(): 20 | ${upgrades if upgrades else "pass"} 21 | 22 | 23 | def downgrade(): 24 | ${downgrades if downgrades else "pass"} 25 | -------------------------------------------------------------------------------- /examples/test_experimental_all_models_register_async/migrations/versions/aaaaaaaaaaaa_create_foo.py: -------------------------------------------------------------------------------- 1 | import sqlalchemy as sa 2 | from alembic import op 3 | 4 | revision = "aaaaaaaaaaaa" 5 | down_revision = None 6 | branch_labels = None 7 | depends_on = None 8 | 9 | 10 | def upgrade(): 11 | op.create_table( 12 | "foo", 13 | sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), 14 | sa.Column( 15 | "created_at", 16 | sa.DateTime(timezone=True), 17 | server_default=sa.text("(CURRENT_TIMESTAMP)"), 18 | nullable=False, 19 | ), 20 | sa.PrimaryKeyConstraint("id"), 21 | ) 22 | 23 | 24 | def downgrade(): 25 | op.drop_table("foo") 26 | -------------------------------------------------------------------------------- /examples/test_experimental_all_models_register_async/migrations/versions/bbbbbbbbbbbb_update_foo.py: -------------------------------------------------------------------------------- 1 | from alembic import op 2 | from sqlalchemy import text 3 | 4 | revision = "bbbbbbbbbbbb" 5 | down_revision = "aaaaaaaaaaaa" 6 | branch_labels = None 7 | depends_on = None 8 | 9 | 10 | def upgrade(): 11 | conn = op.get_bind() 12 | result = conn.execute(text("SELECT * FROM foo")).fetchall() 13 | assert len(result) == 1, result 14 | 15 | 16 | def downgrade(): 17 | pass 18 | -------------------------------------------------------------------------------- /examples/test_experimental_all_models_register_async/models.py: -------------------------------------------------------------------------------- 1 | import sqlalchemy 2 | from sqlalchemy import Column, types 3 | 4 | try: 5 | from sqlalchemy.orm import declarative_base 6 | except ImportError: 7 | from sqlalchemy.ext.declarative import declarative_base 8 | 9 | 10 | Base = declarative_base() 11 | 12 | 13 | class CreatedAt(Base): 14 | __tablename__ = "foo" 15 | 16 | id = Column(types.Integer(), autoincrement=True, primary_key=True) 17 | 18 | created_at = sqlalchemy.Column( 19 | sqlalchemy.types.DateTime(timezone=True), 20 | server_default=sqlalchemy.text("CURRENT_TIMESTAMP"), 21 | nullable=False, 22 | ) 23 | -------------------------------------------------------------------------------- /examples/test_experimental_all_models_register_automatic/alembic.ini: -------------------------------------------------------------------------------- 1 | [alembic] 2 | script_location = migrations 3 | 4 | [loggers] 5 | keys = root,sqlalchemy,alembic 6 | 7 | [handlers] 8 | keys = console 9 | 10 | [formatters] 11 | keys = generic 12 | 13 | [logger_root] 14 | level = WARN 15 | handlers = console 16 | qualname = 17 | 18 | [logger_sqlalchemy] 19 | level = WARN 20 | handlers = 21 | qualname = sqlalchemy.engine 22 | 23 | [logger_alembic] 24 | level = INFO 25 | handlers = 26 | qualname = alembic 27 | 28 | [handler_console] 29 | class = StreamHandler 30 | args = (sys.stderr,) 31 | level = NOTSET 32 | formatter = generic 33 | 34 | [formatter_generic] 35 | format = %(levelname)-5.5s [%(name)s] %(message)s 36 | datefmt = %H:%M:%S 37 | -------------------------------------------------------------------------------- /examples/test_experimental_all_models_register_automatic/conftest.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schireson/pytest-alembic/47748802f22db988fb95926189eb78ec59ad387f/examples/test_experimental_all_models_register_automatic/conftest.py -------------------------------------------------------------------------------- /examples/test_experimental_all_models_register_automatic/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schireson/pytest-alembic/47748802f22db988fb95926189eb78ec59ad387f/examples/test_experimental_all_models_register_automatic/migrations/__init__.py -------------------------------------------------------------------------------- /examples/test_experimental_all_models_register_automatic/migrations/env.py: -------------------------------------------------------------------------------- 1 | from logging.config import fileConfig 2 | 3 | from alembic import context 4 | from models import Base 5 | from sqlalchemy import engine_from_config, pool 6 | 7 | fileConfig(context.config.config_file_name) 8 | target_metadata = Base.metadata 9 | 10 | 11 | connectable = context.config.attributes.get("connection", None) 12 | 13 | if connectable is None: 14 | connectable = engine_from_config( 15 | context.config.get_section(context.config.config_ini_section), 16 | prefix="sqlalchemy.", 17 | poolclass=pool.NullPool, 18 | ) 19 | 20 | with connectable.connect() as connection: 21 | context.configure(connection=connection, target_metadata=target_metadata) 22 | 23 | with context.begin_transaction(): 24 | context.run_migrations() 25 | -------------------------------------------------------------------------------- /examples/test_experimental_all_models_register_automatic/migrations/script.py.mako: -------------------------------------------------------------------------------- 1 | """${message} 2 | 3 | Revision ID: ${up_revision} 4 | Revises: ${down_revision | comma,n} 5 | Create Date: ${create_date} 6 | 7 | """ 8 | from alembic import op 9 | import sqlalchemy as sa 10 | ${imports if imports else ""} 11 | 12 | # revision identifiers, used by Alembic. 13 | revision = ${repr(up_revision)} 14 | down_revision = ${repr(down_revision)} 15 | branch_labels = ${repr(branch_labels)} 16 | depends_on = ${repr(depends_on)} 17 | 18 | 19 | def upgrade(): 20 | ${upgrades if upgrades else "pass"} 21 | 22 | 23 | def downgrade(): 24 | ${downgrades if downgrades else "pass"} 25 | -------------------------------------------------------------------------------- /examples/test_experimental_all_models_register_automatic/migrations/versions/aaaaaaaaaaaa_create_foo.py: -------------------------------------------------------------------------------- 1 | import sqlalchemy as sa 2 | from alembic import op 3 | 4 | revision = "aaaaaaaaaaaa" 5 | down_revision = None 6 | branch_labels = None 7 | depends_on = None 8 | 9 | 10 | def upgrade(): 11 | op.create_table( 12 | "foo", 13 | sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), 14 | sa.Column( 15 | "created_at", 16 | sa.DateTime(timezone=True), 17 | server_default=sa.text("(CURRENT_TIMESTAMP)"), 18 | nullable=False, 19 | ), 20 | sa.PrimaryKeyConstraint("id"), 21 | ) 22 | 23 | 24 | def downgrade(): 25 | op.drop_table("foo") 26 | -------------------------------------------------------------------------------- /examples/test_experimental_all_models_register_automatic/migrations/versions/bbbbbbbbbbbb_update_foo.py: -------------------------------------------------------------------------------- 1 | from alembic import op 2 | from sqlalchemy import text 3 | 4 | revision = "bbbbbbbbbbbb" 5 | down_revision = "aaaaaaaaaaaa" 6 | branch_labels = None 7 | depends_on = None 8 | 9 | 10 | def upgrade(): 11 | conn = op.get_bind() 12 | result = conn.execute(text("SELECT * FROM foo")).fetchall() 13 | assert len(result) == 0 14 | 15 | 16 | def downgrade(): 17 | pass 18 | -------------------------------------------------------------------------------- /examples/test_experimental_all_models_register_automatic/models.py: -------------------------------------------------------------------------------- 1 | import sqlalchemy 2 | from sqlalchemy import Column, types 3 | 4 | try: 5 | from sqlalchemy.orm import declarative_base 6 | except ImportError: 7 | from sqlalchemy.ext.declarative import declarative_base 8 | 9 | 10 | Base = declarative_base() 11 | 12 | 13 | class CreatedAt(Base): 14 | __tablename__ = "foo" 15 | 16 | id = Column(types.Integer(), autoincrement=True, primary_key=True) 17 | 18 | created_at = sqlalchemy.Column( 19 | sqlalchemy.types.DateTime(timezone=True), 20 | server_default=sqlalchemy.text("CURRENT_TIMESTAMP"), 21 | nullable=False, 22 | ) 23 | -------------------------------------------------------------------------------- /examples/test_experimental_all_models_register_automatic/pyproject.toml: -------------------------------------------------------------------------------- 1 | [tool.pytest.ini_options] 2 | pytest_alembic_include_experimental = 'all_models_register_on_metadata' 3 | -------------------------------------------------------------------------------- /examples/test_experimental_all_models_register_failure/alembic.ini: -------------------------------------------------------------------------------- 1 | [alembic] 2 | script_location = migrations 3 | 4 | [loggers] 5 | keys = root,sqlalchemy,alembic 6 | 7 | [handlers] 8 | keys = console 9 | 10 | [formatters] 11 | keys = generic 12 | 13 | [logger_root] 14 | level = WARN 15 | handlers = console 16 | qualname = 17 | 18 | [logger_sqlalchemy] 19 | level = WARN 20 | handlers = 21 | qualname = sqlalchemy.engine 22 | 23 | [logger_alembic] 24 | level = INFO 25 | handlers = 26 | qualname = alembic 27 | 28 | [handler_console] 29 | class = StreamHandler 30 | args = (sys.stderr,) 31 | level = NOTSET 32 | formatter = generic 33 | 34 | [formatter_generic] 35 | format = %(levelname)-5.5s [%(name)s] %(message)s 36 | datefmt = %H:%M:%S 37 | -------------------------------------------------------------------------------- /examples/test_experimental_all_models_register_failure/conftest.py: -------------------------------------------------------------------------------- 1 | import pytest_alembic.tests.experimental 2 | 3 | 4 | def test_all_models_register_on_metadata(alembic_runner): 5 | pytest_alembic.tests.experimental.test_all_models_register_on_metadata(alembic_runner, "models") 6 | -------------------------------------------------------------------------------- /examples/test_experimental_all_models_register_failure/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schireson/pytest-alembic/47748802f22db988fb95926189eb78ec59ad387f/examples/test_experimental_all_models_register_failure/migrations/__init__.py -------------------------------------------------------------------------------- /examples/test_experimental_all_models_register_failure/migrations/env.py: -------------------------------------------------------------------------------- 1 | from logging.config import fileConfig 2 | 3 | from alembic import context 4 | from models import Base 5 | from sqlalchemy import engine_from_config, pool 6 | 7 | fileConfig(context.config.config_file_name) 8 | target_metadata = Base.metadata 9 | 10 | 11 | connectable = context.config.attributes.get("connection", None) 12 | 13 | if connectable is None: 14 | connectable = engine_from_config( 15 | context.config.get_section(context.config.config_ini_section), 16 | prefix="sqlalchemy.", 17 | poolclass=pool.NullPool, 18 | ) 19 | 20 | with connectable.connect() as connection: 21 | context.configure(connection=connection, target_metadata=target_metadata) 22 | 23 | with context.begin_transaction(): 24 | context.run_migrations() 25 | -------------------------------------------------------------------------------- /examples/test_experimental_all_models_register_failure/migrations/script.py.mako: -------------------------------------------------------------------------------- 1 | """${message} 2 | 3 | Revision ID: ${up_revision} 4 | Revises: ${down_revision | comma,n} 5 | Create Date: ${create_date} 6 | 7 | """ 8 | from alembic import op 9 | import sqlalchemy as sa 10 | ${imports if imports else ""} 11 | 12 | # revision identifiers, used by Alembic. 13 | revision = ${repr(up_revision)} 14 | down_revision = ${repr(down_revision)} 15 | branch_labels = ${repr(branch_labels)} 16 | depends_on = ${repr(depends_on)} 17 | 18 | 19 | def upgrade(): 20 | ${upgrades if upgrades else "pass"} 21 | 22 | 23 | def downgrade(): 24 | ${downgrades if downgrades else "pass"} 25 | -------------------------------------------------------------------------------- /examples/test_experimental_all_models_register_failure/migrations/versions/aaaaaaaaaaaa_create_foo.py: -------------------------------------------------------------------------------- 1 | import sqlalchemy as sa 2 | from alembic import op 3 | 4 | revision = "aaaaaaaaaaaa" 5 | down_revision = None 6 | branch_labels = None 7 | depends_on = None 8 | 9 | 10 | def upgrade(): 11 | op.create_table( 12 | "foo", 13 | sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), 14 | sa.Column( 15 | "created_at", 16 | sa.DateTime(timezone=True), 17 | server_default=sa.text("(CURRENT_TIMESTAMP)"), 18 | nullable=False, 19 | ), 20 | sa.PrimaryKeyConstraint("id"), 21 | ) 22 | 23 | 24 | def downgrade(): 25 | op.drop_table("foo") 26 | -------------------------------------------------------------------------------- /examples/test_experimental_all_models_register_failure/migrations/versions/bbbbbbbbbbbb_update_foo.py: -------------------------------------------------------------------------------- 1 | from alembic import op 2 | from sqlalchemy import text 3 | 4 | revision = "bbbbbbbbbbbb" 5 | down_revision = "aaaaaaaaaaaa" 6 | branch_labels = None 7 | depends_on = None 8 | 9 | 10 | def upgrade(): 11 | conn = op.get_bind() 12 | result = conn.execute(text("SELECT * FROM foo")).fetchall() 13 | assert len(result) == 0 14 | 15 | 16 | def downgrade(): 17 | pass 18 | -------------------------------------------------------------------------------- /examples/test_experimental_all_models_register_failure/models/__init__.py: -------------------------------------------------------------------------------- 1 | import sqlalchemy 2 | from sqlalchemy import Column, types 3 | 4 | try: 5 | from sqlalchemy.orm import declarative_base 6 | except ImportError: 7 | from sqlalchemy.ext.declarative import declarative_base 8 | 9 | 10 | Base = declarative_base() 11 | 12 | 13 | class CreatedAt(Base): 14 | __tablename__ = "foo" 15 | 16 | id = Column(types.Integer(), autoincrement=True, primary_key=True) 17 | 18 | created_at = sqlalchemy.Column( 19 | sqlalchemy.types.DateTime(timezone=True), 20 | server_default=sqlalchemy.text("CURRENT_TIMESTAMP"), 21 | nullable=False, 22 | ) 23 | -------------------------------------------------------------------------------- /examples/test_experimental_all_models_register_failure/models/bar.py: -------------------------------------------------------------------------------- 1 | from sqlalchemy import Column, types 2 | 3 | from models import Base 4 | 5 | 6 | class Bar(Base): 7 | __tablename__ = "bar" 8 | 9 | id = Column(types.Integer(), autoincrement=True, primary_key=True) 10 | -------------------------------------------------------------------------------- /examples/test_experimental_all_models_register_metadata/alembic.ini: -------------------------------------------------------------------------------- 1 | [alembic] 2 | script_location = migrations 3 | 4 | [loggers] 5 | keys = root,sqlalchemy,alembic 6 | 7 | [handlers] 8 | keys = console 9 | 10 | [formatters] 11 | keys = generic 12 | 13 | [logger_root] 14 | level = WARN 15 | handlers = console 16 | qualname = 17 | 18 | [logger_sqlalchemy] 19 | level = WARN 20 | handlers = 21 | qualname = sqlalchemy.engine 22 | 23 | [logger_alembic] 24 | level = INFO 25 | handlers = 26 | qualname = alembic 27 | 28 | [handler_console] 29 | class = StreamHandler 30 | args = (sys.stderr,) 31 | level = NOTSET 32 | formatter = generic 33 | 34 | [formatter_generic] 35 | format = %(levelname)-5.5s [%(name)s] %(message)s 36 | datefmt = %H:%M:%S 37 | -------------------------------------------------------------------------------- /examples/test_experimental_all_models_register_metadata/conftest.py: -------------------------------------------------------------------------------- 1 | import pytest_alembic.tests.experimental 2 | 3 | 4 | def test_all_models_register_on_metadata(alembic_runner): 5 | pytest_alembic.tests.experimental.test_all_models_register_on_metadata(alembic_runner, "models") 6 | -------------------------------------------------------------------------------- /examples/test_experimental_all_models_register_metadata/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schireson/pytest-alembic/47748802f22db988fb95926189eb78ec59ad387f/examples/test_experimental_all_models_register_metadata/migrations/__init__.py -------------------------------------------------------------------------------- /examples/test_experimental_all_models_register_metadata/migrations/env.py: -------------------------------------------------------------------------------- 1 | from logging.config import fileConfig 2 | 3 | from alembic import context 4 | from models import metadata 5 | from sqlalchemy import engine_from_config, pool 6 | 7 | fileConfig(context.config.config_file_name) 8 | 9 | 10 | connectable = context.config.attributes.get("connection", None) 11 | 12 | if connectable is None: 13 | connectable = engine_from_config( 14 | context.config.get_section(context.config.config_ini_section), 15 | prefix="sqlalchemy.", 16 | poolclass=pool.NullPool, 17 | ) 18 | 19 | with connectable.connect() as connection: 20 | context.configure(connection=connection, target_metadata=metadata) 21 | 22 | with context.begin_transaction(): 23 | context.run_migrations() 24 | -------------------------------------------------------------------------------- /examples/test_experimental_all_models_register_metadata/migrations/script.py.mako: -------------------------------------------------------------------------------- 1 | """${message} 2 | 3 | Revision ID: ${up_revision} 4 | Revises: ${down_revision | comma,n} 5 | Create Date: ${create_date} 6 | 7 | """ 8 | from alembic import op 9 | import sqlalchemy as sa 10 | ${imports if imports else ""} 11 | 12 | # revision identifiers, used by Alembic. 13 | revision = ${repr(up_revision)} 14 | down_revision = ${repr(down_revision)} 15 | branch_labels = ${repr(branch_labels)} 16 | depends_on = ${repr(depends_on)} 17 | 18 | 19 | def upgrade(): 20 | ${upgrades if upgrades else "pass"} 21 | 22 | 23 | def downgrade(): 24 | ${downgrades if downgrades else "pass"} 25 | -------------------------------------------------------------------------------- /examples/test_experimental_all_models_register_metadata/migrations/versions/aaaaaaaaaaaa_create_foo.py: -------------------------------------------------------------------------------- 1 | import sqlalchemy as sa 2 | from alembic import op 3 | 4 | revision = "aaaaaaaaaaaa" 5 | down_revision = None 6 | branch_labels = None 7 | depends_on = None 8 | 9 | 10 | def upgrade(): 11 | op.create_table( 12 | "foo", 13 | sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), 14 | sa.Column( 15 | "created_at", 16 | sa.DateTime(timezone=True), 17 | server_default=sa.text("(CURRENT_TIMESTAMP)"), 18 | nullable=False, 19 | ), 20 | sa.PrimaryKeyConstraint("id"), 21 | ) 22 | 23 | 24 | def downgrade(): 25 | op.drop_table("foo") 26 | -------------------------------------------------------------------------------- /examples/test_experimental_all_models_register_metadata/migrations/versions/bbbbbbbbbbbb_update_foo.py: -------------------------------------------------------------------------------- 1 | from alembic import op 2 | from sqlalchemy import text 3 | 4 | revision = "bbbbbbbbbbbb" 5 | down_revision = "aaaaaaaaaaaa" 6 | branch_labels = None 7 | depends_on = None 8 | 9 | 10 | def upgrade(): 11 | conn = op.get_bind() 12 | result = conn.execute(text("SELECT * FROM foo")).fetchall() 13 | assert len(result) == 0 14 | 15 | 16 | def downgrade(): 17 | pass 18 | -------------------------------------------------------------------------------- /examples/test_experimental_all_models_register_metadata/models.py: -------------------------------------------------------------------------------- 1 | from sqlalchemy import MetaData 2 | 3 | metadata = MetaData() 4 | -------------------------------------------------------------------------------- /examples/test_experimental_all_models_register_namespace_package/alembic.ini: -------------------------------------------------------------------------------- 1 | [alembic] 2 | script_location = migrations 3 | 4 | [loggers] 5 | keys = root,sqlalchemy,alembic 6 | 7 | [handlers] 8 | keys = console 9 | 10 | [formatters] 11 | keys = generic 12 | 13 | [logger_root] 14 | level = WARN 15 | handlers = console 16 | qualname = 17 | 18 | [logger_sqlalchemy] 19 | level = WARN 20 | handlers = 21 | qualname = sqlalchemy.engine 22 | 23 | [logger_alembic] 24 | level = INFO 25 | handlers = 26 | qualname = alembic 27 | 28 | [handler_console] 29 | class = StreamHandler 30 | args = (sys.stderr,) 31 | level = NOTSET 32 | formatter = generic 33 | 34 | [formatter_generic] 35 | format = %(levelname)-5.5s [%(name)s] %(message)s 36 | datefmt = %H:%M:%S 37 | -------------------------------------------------------------------------------- /examples/test_experimental_all_models_register_namespace_package/conftest.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schireson/pytest-alembic/47748802f22db988fb95926189eb78ec59ad387f/examples/test_experimental_all_models_register_namespace_package/conftest.py -------------------------------------------------------------------------------- /examples/test_experimental_all_models_register_namespace_package/foo/bar/__init__.py: -------------------------------------------------------------------------------- 1 | import sqlalchemy 2 | from sqlalchemy import Column, types 3 | 4 | try: 5 | from sqlalchemy.orm import declarative_base 6 | except ImportError: 7 | from sqlalchemy.ext.declarative import declarative_base 8 | 9 | 10 | Base = declarative_base() 11 | 12 | 13 | class CreatedAt(Base): 14 | __tablename__ = "foo" 15 | 16 | id = Column(types.Integer(), autoincrement=True, primary_key=True) 17 | 18 | created_at = sqlalchemy.Column( 19 | sqlalchemy.types.DateTime(timezone=True), 20 | server_default=sqlalchemy.text("CURRENT_TIMESTAMP"), 21 | nullable=False, 22 | ) 23 | -------------------------------------------------------------------------------- /examples/test_experimental_all_models_register_namespace_package/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schireson/pytest-alembic/47748802f22db988fb95926189eb78ec59ad387f/examples/test_experimental_all_models_register_namespace_package/migrations/__init__.py -------------------------------------------------------------------------------- /examples/test_experimental_all_models_register_namespace_package/migrations/env.py: -------------------------------------------------------------------------------- 1 | import sys 2 | from logging.config import fileConfig 3 | from pathlib import Path 4 | 5 | from alembic import context 6 | from sqlalchemy import engine_from_config, pool 7 | 8 | sys.path.append(str(Path().resolve())) 9 | 10 | from foo.bar import Base # noqa: E402 11 | 12 | fileConfig(context.config.config_file_name) 13 | target_metadata = Base.metadata 14 | 15 | 16 | connectable = context.config.attributes.get("connection", None) 17 | 18 | if connectable is None: 19 | connectable = engine_from_config( 20 | context.config.get_section(context.config.config_ini_section), 21 | prefix="sqlalchemy.", 22 | poolclass=pool.NullPool, 23 | ) 24 | 25 | with connectable.connect() as connection: 26 | context.configure(connection=connection, target_metadata=target_metadata) 27 | 28 | with context.begin_transaction(): 29 | context.run_migrations() 30 | -------------------------------------------------------------------------------- /examples/test_experimental_all_models_register_namespace_package/migrations/script.py.mako: -------------------------------------------------------------------------------- 1 | """${message} 2 | 3 | Revision ID: ${up_revision} 4 | Revises: ${down_revision | comma,n} 5 | Create Date: ${create_date} 6 | 7 | """ 8 | from alembic import op 9 | import sqlalchemy as sa 10 | ${imports if imports else ""} 11 | 12 | # revision identifiers, used by Alembic. 13 | revision = ${repr(up_revision)} 14 | down_revision = ${repr(down_revision)} 15 | branch_labels = ${repr(branch_labels)} 16 | depends_on = ${repr(depends_on)} 17 | 18 | 19 | def upgrade(): 20 | ${upgrades if upgrades else "pass"} 21 | 22 | 23 | def downgrade(): 24 | ${downgrades if downgrades else "pass"} 25 | -------------------------------------------------------------------------------- /examples/test_experimental_all_models_register_namespace_package/migrations/versions/aaaaaaaaaaaa_create_foo.py: -------------------------------------------------------------------------------- 1 | import sqlalchemy as sa 2 | from alembic import op 3 | 4 | revision = "aaaaaaaaaaaa" 5 | down_revision = None 6 | branch_labels = None 7 | depends_on = None 8 | 9 | 10 | def upgrade(): 11 | op.create_table( 12 | "foo", 13 | sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), 14 | sa.Column( 15 | "created_at", 16 | sa.DateTime(timezone=True), 17 | server_default=sa.text("(CURRENT_TIMESTAMP)"), 18 | nullable=False, 19 | ), 20 | sa.PrimaryKeyConstraint("id"), 21 | ) 22 | 23 | 24 | def downgrade(): 25 | op.drop_table("foo") 26 | -------------------------------------------------------------------------------- /examples/test_experimental_all_models_register_namespace_package/migrations/versions/bbbbbbbbbbbb_update_foo.py: -------------------------------------------------------------------------------- 1 | from alembic import op 2 | from sqlalchemy import text 3 | 4 | revision = "bbbbbbbbbbbb" 5 | down_revision = "aaaaaaaaaaaa" 6 | branch_labels = None 7 | depends_on = None 8 | 9 | 10 | def upgrade(): 11 | conn = op.get_bind() 12 | result = conn.execute(text("SELECT * FROM foo")).fetchall() 13 | assert len(result) == 0 14 | 15 | 16 | def downgrade(): 17 | pass 18 | -------------------------------------------------------------------------------- /examples/test_experimental_all_models_register_namespace_package/pyproject.toml: -------------------------------------------------------------------------------- 1 | [tool.pytest.ini_options] 2 | pytest_alembic_include_experimental = 'all_models_register_on_metadata' 3 | -------------------------------------------------------------------------------- /examples/test_experimental_all_models_register_no_metadata/alembic.ini: -------------------------------------------------------------------------------- 1 | [alembic] 2 | script_location = migrations 3 | 4 | [loggers] 5 | keys = root,sqlalchemy,alembic 6 | 7 | [handlers] 8 | keys = console 9 | 10 | [formatters] 11 | keys = generic 12 | 13 | [logger_root] 14 | level = WARN 15 | handlers = console 16 | qualname = 17 | 18 | [logger_sqlalchemy] 19 | level = WARN 20 | handlers = 21 | qualname = sqlalchemy.engine 22 | 23 | [logger_alembic] 24 | level = INFO 25 | handlers = 26 | qualname = alembic 27 | 28 | [handler_console] 29 | class = StreamHandler 30 | args = (sys.stderr,) 31 | level = NOTSET 32 | formatter = generic 33 | 34 | [formatter_generic] 35 | format = %(levelname)-5.5s [%(name)s] %(message)s 36 | datefmt = %H:%M:%S 37 | -------------------------------------------------------------------------------- /examples/test_experimental_all_models_register_no_metadata/conftest.py: -------------------------------------------------------------------------------- 1 | import pytest_alembic.tests.experimental 2 | 3 | 4 | def test_all_models_register_on_metadata(alembic_runner): 5 | pytest_alembic.tests.experimental.test_all_models_register_on_metadata(alembic_runner, "models") 6 | -------------------------------------------------------------------------------- /examples/test_experimental_all_models_register_no_metadata/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schireson/pytest-alembic/47748802f22db988fb95926189eb78ec59ad387f/examples/test_experimental_all_models_register_no_metadata/migrations/__init__.py -------------------------------------------------------------------------------- /examples/test_experimental_all_models_register_no_metadata/migrations/env.py: -------------------------------------------------------------------------------- 1 | from logging.config import fileConfig 2 | 3 | from alembic import context 4 | from sqlalchemy import engine_from_config, pool 5 | 6 | fileConfig(context.config.config_file_name) 7 | 8 | 9 | connectable = context.config.attributes.get("connection", None) 10 | 11 | if connectable is None: 12 | connectable = engine_from_config( 13 | context.config.get_section(context.config.config_ini_section), 14 | prefix="sqlalchemy.", 15 | poolclass=pool.NullPool, 16 | ) 17 | 18 | with connectable.connect() as connection: 19 | context.configure(connection=connection) 20 | 21 | with context.begin_transaction(): 22 | context.run_migrations() 23 | -------------------------------------------------------------------------------- /examples/test_experimental_all_models_register_no_metadata/migrations/script.py.mako: -------------------------------------------------------------------------------- 1 | """${message} 2 | 3 | Revision ID: ${up_revision} 4 | Revises: ${down_revision | comma,n} 5 | Create Date: ${create_date} 6 | 7 | """ 8 | from alembic import op 9 | import sqlalchemy as sa 10 | ${imports if imports else ""} 11 | 12 | # revision identifiers, used by Alembic. 13 | revision = ${repr(up_revision)} 14 | down_revision = ${repr(down_revision)} 15 | branch_labels = ${repr(branch_labels)} 16 | depends_on = ${repr(depends_on)} 17 | 18 | 19 | def upgrade(): 20 | ${upgrades if upgrades else "pass"} 21 | 22 | 23 | def downgrade(): 24 | ${downgrades if downgrades else "pass"} 25 | -------------------------------------------------------------------------------- /examples/test_experimental_all_models_register_no_metadata/migrations/versions/aaaaaaaaaaaa_create_foo.py: -------------------------------------------------------------------------------- 1 | import sqlalchemy as sa 2 | from alembic import op 3 | 4 | revision = "aaaaaaaaaaaa" 5 | down_revision = None 6 | branch_labels = None 7 | depends_on = None 8 | 9 | 10 | def upgrade(): 11 | op.create_table( 12 | "foo", 13 | sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), 14 | sa.Column( 15 | "created_at", 16 | sa.DateTime(timezone=True), 17 | server_default=sa.text("(CURRENT_TIMESTAMP)"), 18 | nullable=False, 19 | ), 20 | sa.PrimaryKeyConstraint("id"), 21 | ) 22 | 23 | 24 | def downgrade(): 25 | op.drop_table("foo") 26 | -------------------------------------------------------------------------------- /examples/test_experimental_all_models_register_no_metadata/migrations/versions/bbbbbbbbbbbb_update_foo.py: -------------------------------------------------------------------------------- 1 | from alembic import op 2 | from sqlalchemy import text 3 | 4 | revision = "bbbbbbbbbbbb" 5 | down_revision = "aaaaaaaaaaaa" 6 | branch_labels = None 7 | depends_on = None 8 | 9 | 10 | def upgrade(): 11 | conn = op.get_bind() 12 | result = conn.execute(text("SELECT * FROM foo")).fetchall() 13 | assert len(result) == 0 14 | 15 | 16 | def downgrade(): 17 | pass 18 | -------------------------------------------------------------------------------- /examples/test_experimental_all_models_register_no_metadata/models.py: -------------------------------------------------------------------------------- 1 | # No MetaData 2 | -------------------------------------------------------------------------------- /examples/test_experimental_all_models_register_offline/alembic.ini: -------------------------------------------------------------------------------- 1 | [alembic] 2 | script_location = migrations 3 | 4 | [loggers] 5 | keys = root,sqlalchemy,alembic 6 | 7 | [handlers] 8 | keys = console 9 | 10 | [formatters] 11 | keys = generic 12 | 13 | [logger_root] 14 | level = WARN 15 | handlers = console 16 | qualname = 17 | 18 | [logger_sqlalchemy] 19 | level = WARN 20 | handlers = 21 | qualname = sqlalchemy.engine 22 | 23 | [logger_alembic] 24 | level = INFO 25 | handlers = 26 | qualname = alembic 27 | 28 | [handler_console] 29 | class = StreamHandler 30 | args = (sys.stderr,) 31 | level = NOTSET 32 | formatter = generic 33 | 34 | [formatter_generic] 35 | format = %(levelname)-5.5s [%(name)s] %(message)s 36 | datefmt = %H:%M:%S 37 | -------------------------------------------------------------------------------- /examples/test_experimental_all_models_register_offline/conftest.py: -------------------------------------------------------------------------------- 1 | import pytest_alembic.tests.experimental 2 | 3 | 4 | def test_all_models_register_on_metadata(alembic_runner): 5 | pytest_alembic.tests.experimental.test_all_models_register_on_metadata( 6 | alembic_runner, "models", offline=True 7 | ) 8 | -------------------------------------------------------------------------------- /examples/test_experimental_all_models_register_offline/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schireson/pytest-alembic/47748802f22db988fb95926189eb78ec59ad387f/examples/test_experimental_all_models_register_offline/migrations/__init__.py -------------------------------------------------------------------------------- /examples/test_experimental_all_models_register_offline/migrations/script.py.mako: -------------------------------------------------------------------------------- 1 | """${message} 2 | 3 | Revision ID: ${up_revision} 4 | Revises: ${down_revision | comma,n} 5 | Create Date: ${create_date} 6 | 7 | """ 8 | from alembic import op 9 | import sqlalchemy as sa 10 | ${imports if imports else ""} 11 | 12 | # revision identifiers, used by Alembic. 13 | revision = ${repr(up_revision)} 14 | down_revision = ${repr(down_revision)} 15 | branch_labels = ${repr(branch_labels)} 16 | depends_on = ${repr(depends_on)} 17 | 18 | 19 | def upgrade(): 20 | ${upgrades if upgrades else "pass"} 21 | 22 | 23 | def downgrade(): 24 | ${downgrades if downgrades else "pass"} 25 | -------------------------------------------------------------------------------- /examples/test_experimental_all_models_register_offline/migrations/versions/aaaaaaaaaaaa_create_foo.py: -------------------------------------------------------------------------------- 1 | import sqlalchemy as sa 2 | from alembic import op 3 | 4 | revision = "aaaaaaaaaaaa" 5 | down_revision = None 6 | branch_labels = None 7 | depends_on = None 8 | 9 | 10 | def upgrade(): 11 | op.create_table( 12 | "foo", 13 | sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), 14 | sa.Column( 15 | "created_at", 16 | sa.DateTime(timezone=True), 17 | server_default=sa.text("(CURRENT_TIMESTAMP)"), 18 | nullable=False, 19 | ), 20 | sa.PrimaryKeyConstraint("id"), 21 | ) 22 | 23 | 24 | def downgrade(): 25 | op.drop_table("foo") 26 | -------------------------------------------------------------------------------- /examples/test_experimental_all_models_register_offline/migrations/versions/bbbbbbbbbbbb_update_foo.py: -------------------------------------------------------------------------------- 1 | from alembic import op 2 | from sqlalchemy import text 3 | 4 | revision = "bbbbbbbbbbbb" 5 | down_revision = "aaaaaaaaaaaa" 6 | branch_labels = None 7 | depends_on = None 8 | 9 | 10 | def upgrade(): 11 | conn = op.get_bind() 12 | result = conn.execute(text("SELECT * FROM foo")).fetchall() 13 | assert len(result) == 0 14 | 15 | 16 | def downgrade(): 17 | pass 18 | -------------------------------------------------------------------------------- /examples/test_experimental_all_models_register_offline/models.py: -------------------------------------------------------------------------------- 1 | import sqlalchemy 2 | from sqlalchemy import Column, types 3 | 4 | try: 5 | from sqlalchemy.orm import declarative_base 6 | except ImportError: 7 | from sqlalchemy.ext.declarative import declarative_base 8 | 9 | 10 | Base = declarative_base() 11 | 12 | 13 | class CreatedAt(Base): 14 | __tablename__ = "foo" 15 | 16 | id = Column(types.Integer(), autoincrement=True, primary_key=True) 17 | 18 | created_at = sqlalchemy.Column( 19 | sqlalchemy.types.DateTime(timezone=True), 20 | server_default=sqlalchemy.text("CURRENT_TIMESTAMP"), 21 | nullable=False, 22 | ) 23 | -------------------------------------------------------------------------------- /examples/test_failing_downgrade/alembic.ini: -------------------------------------------------------------------------------- 1 | [alembic] 2 | script_location = migrations 3 | 4 | [loggers] 5 | keys = root,sqlalchemy,alembic 6 | 7 | [handlers] 8 | keys = console 9 | 10 | [formatters] 11 | keys = generic 12 | 13 | [logger_root] 14 | level = WARN 15 | handlers = console 16 | qualname = 17 | 18 | [logger_sqlalchemy] 19 | level = WARN 20 | handlers = 21 | qualname = sqlalchemy.engine 22 | 23 | [logger_alembic] 24 | level = INFO 25 | handlers = 26 | qualname = alembic 27 | 28 | [handler_console] 29 | class = StreamHandler 30 | args = (sys.stderr,) 31 | level = NOTSET 32 | formatter = generic 33 | 34 | [formatter_generic] 35 | format = %(levelname)-5.5s [%(name)s] %(message)s 36 | datefmt = %H:%M:%S 37 | -------------------------------------------------------------------------------- /examples/test_failing_downgrade/conftest.py: -------------------------------------------------------------------------------- 1 | from pytest_mock_resources import create_postgres_fixture 2 | 3 | alembic_engine = create_postgres_fixture() 4 | -------------------------------------------------------------------------------- /examples/test_failing_downgrade/migrations/env.py: -------------------------------------------------------------------------------- 1 | from logging.config import fileConfig 2 | 3 | from alembic import context 4 | from models import Base 5 | from sqlalchemy import engine_from_config, pool 6 | 7 | fileConfig(context.config.config_file_name) 8 | target_metadata = Base.metadata 9 | 10 | 11 | connectable = context.config.attributes.get("connection", None) 12 | 13 | if connectable is None: 14 | connectable = engine_from_config( 15 | context.config.get_section(context.config.config_ini_section), 16 | prefix="sqlalchemy.", 17 | poolclass=pool.NullPool, 18 | ) 19 | 20 | with connectable.connect() as connection: 21 | context.configure(connection=connection, target_metadata=target_metadata) 22 | 23 | with context.begin_transaction(): 24 | context.run_migrations() 25 | -------------------------------------------------------------------------------- /examples/test_failing_downgrade/migrations/script.py.mako: -------------------------------------------------------------------------------- 1 | """${message} 2 | 3 | Revision ID: ${up_revision} 4 | Revises: ${down_revision | comma,n} 5 | Create Date: ${create_date} 6 | 7 | """ 8 | from alembic import op 9 | import sqlalchemy as sa 10 | ${imports if imports else ""} 11 | 12 | # revision identifiers, used by Alembic. 13 | revision = ${repr(up_revision)} 14 | down_revision = ${repr(down_revision)} 15 | branch_labels = ${repr(branch_labels)} 16 | depends_on = ${repr(depends_on)} 17 | 18 | 19 | def upgrade(): 20 | ${upgrades if upgrades else "pass"} 21 | 22 | 23 | def downgrade(): 24 | ${downgrades if downgrades else "pass"} 25 | -------------------------------------------------------------------------------- /examples/test_failing_downgrade/migrations/versions/aaaaaaaaaaaa_create_foo.py: -------------------------------------------------------------------------------- 1 | import sqlalchemy as sa 2 | from alembic import op 3 | 4 | revision = "aaaaaaaaaaaa" 5 | down_revision = None 6 | branch_labels = None 7 | depends_on = None 8 | 9 | 10 | def upgrade(): 11 | op.create_table( 12 | "foo", 13 | sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), 14 | sa.PrimaryKeyConstraint("id"), 15 | ) 16 | 17 | 18 | def downgrade(): 19 | op.drop_table("foo") 20 | -------------------------------------------------------------------------------- /examples/test_failing_downgrade/migrations/versions/bbbbbbbbbbbb_create_foo.py: -------------------------------------------------------------------------------- 1 | from alembic import op 2 | 3 | revision = "bbbbbbbbbbbb" 4 | down_revision = "aaaaaaaaaaaa" 5 | branch_labels = None 6 | depends_on = None 7 | 8 | 9 | def upgrade(): 10 | op.get_bind() 11 | op.execute("DELETE FROM foo") 12 | 13 | 14 | def downgrade(): 15 | msg = "Something went wrong!" 16 | raise ValueError(msg) 17 | -------------------------------------------------------------------------------- /examples/test_failing_downgrade/migrations/versions/cccccccccccc_create_foo.py: -------------------------------------------------------------------------------- 1 | import sqlalchemy as sa 2 | from alembic import op 3 | 4 | revision = "cccccccccccc" 5 | down_revision = "bbbbbbbbbbbb" 6 | branch_labels = None 7 | depends_on = None 8 | 9 | 10 | def upgrade(): 11 | op.add_column("foo", sa.Column("foo_id", sa.Integer(), server_default="9")) 12 | 13 | 14 | def downgrade(): 15 | op.drop_column("foo", "foo_id") 16 | -------------------------------------------------------------------------------- /examples/test_failing_downgrade/models.py: -------------------------------------------------------------------------------- 1 | from sqlalchemy import Column, types 2 | 3 | try: 4 | from sqlalchemy.orm import declarative_base 5 | except ImportError: 6 | from sqlalchemy.ext.declarative import declarative_base 7 | 8 | 9 | Base = declarative_base() 10 | 11 | 12 | class CreatedAt(Base): 13 | __tablename__ = "foo" 14 | 15 | id = Column(types.Integer(), autoincrement=True, primary_key=True) 16 | foo_id = Column(types.Integer()) 17 | -------------------------------------------------------------------------------- /examples/test_failing_downgrade/setup.cfg: -------------------------------------------------------------------------------- 1 | [tool:pytest] 2 | pytest_alembic_include_experimental = downgrade_leaves_no_trace 3 | -------------------------------------------------------------------------------- /examples/test_generate_revision/alembic.ini: -------------------------------------------------------------------------------- 1 | [alembic] 2 | script_location = migrations 3 | 4 | [loggers] 5 | keys = root,sqlalchemy,alembic 6 | 7 | [handlers] 8 | keys = console 9 | 10 | [formatters] 11 | keys = generic 12 | 13 | [logger_root] 14 | level = WARN 15 | handlers = console 16 | qualname = 17 | 18 | [logger_sqlalchemy] 19 | level = WARN 20 | handlers = 21 | qualname = sqlalchemy.engine 22 | 23 | [logger_alembic] 24 | level = INFO 25 | handlers = 26 | qualname = alembic 27 | 28 | [handler_console] 29 | class = StreamHandler 30 | args = (sys.stderr,) 31 | level = NOTSET 32 | formatter = generic 33 | 34 | [formatter_generic] 35 | format = %(levelname)-5.5s [%(name)s] %(message)s 36 | datefmt = %H:%M:%S 37 | -------------------------------------------------------------------------------- /examples/test_generate_revision/conftest.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schireson/pytest-alembic/47748802f22db988fb95926189eb78ec59ad387f/examples/test_generate_revision/conftest.py -------------------------------------------------------------------------------- /examples/test_generate_revision/migrations/env.py: -------------------------------------------------------------------------------- 1 | from logging.config import fileConfig 2 | 3 | from alembic import context 4 | from models import Base 5 | from sqlalchemy import engine_from_config, pool 6 | 7 | fileConfig(context.config.config_file_name) 8 | target_metadata = Base.metadata 9 | 10 | 11 | connectable = context.config.attributes.get("connection", None) 12 | 13 | if connectable is None: 14 | connectable = engine_from_config( 15 | context.config.get_section(context.config.config_ini_section), 16 | prefix="sqlalchemy.", 17 | poolclass=pool.NullPool, 18 | ) 19 | 20 | with connectable.connect() as connection: 21 | context.configure(connection=connection, target_metadata=target_metadata) 22 | 23 | with context.begin_transaction(): 24 | context.run_migrations() 25 | -------------------------------------------------------------------------------- /examples/test_generate_revision/migrations/script.py.mako: -------------------------------------------------------------------------------- 1 | """${message} 2 | 3 | Revision ID: ${up_revision} 4 | Revises: ${down_revision | comma,n} 5 | Create Date: ${create_date} 6 | 7 | """ 8 | from alembic import op 9 | import sqlalchemy as sa 10 | ${imports if imports else ""} 11 | 12 | # revision identifiers, used by Alembic. 13 | revision = ${repr(up_revision)} 14 | down_revision = ${repr(down_revision)} 15 | branch_labels = ${repr(branch_labels)} 16 | depends_on = ${repr(depends_on)} 17 | 18 | 19 | def upgrade(): 20 | ${upgrades if upgrades else "pass"} 21 | 22 | 23 | def downgrade(): 24 | ${downgrades if downgrades else "pass"} 25 | -------------------------------------------------------------------------------- /examples/test_generate_revision/migrations/versions/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schireson/pytest-alembic/47748802f22db988fb95926189eb78ec59ad387f/examples/test_generate_revision/migrations/versions/.gitkeep -------------------------------------------------------------------------------- /examples/test_generate_revision/models.py: -------------------------------------------------------------------------------- 1 | from sqlalchemy import Column, types 2 | 3 | try: 4 | from sqlalchemy.orm import declarative_base 5 | except ImportError: 6 | from sqlalchemy.ext.declarative import declarative_base 7 | 8 | 9 | Base = declarative_base() 10 | 11 | 12 | class Foo(Base): 13 | __tablename__ = "foo" 14 | 15 | id = Column(types.Integer(), primary_key=True) 16 | -------------------------------------------------------------------------------- /examples/test_generate_revision/setup.cfg: -------------------------------------------------------------------------------- 1 | [tool:pytest] 2 | pytest_alembic_exclude = model_definitions_match_ddl, single_head_revision 3 | -------------------------------------------------------------------------------- /examples/test_generate_revision/test_migration.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | from sqlalchemy import text 3 | 4 | from pytest_alembic.runner import MigrationContext 5 | 6 | 7 | def test_generate_revision(alembic_runner: MigrationContext, alembic_engine): 8 | with pytest.raises(Exception, match=r".*no such table.*"), alembic_engine.connect() as conn: 9 | conn.execute(text("SELECT * FROM foo")).fetchall() 10 | 11 | alembic_runner.generate_revision(autogenerate=True, prevent_file_generation=False) 12 | alembic_runner.migrate_up_one() 13 | 14 | with alembic_engine.begin() as conn: 15 | conn.execute(text("INSERT INTO foo (id) VALUES (100)")) 16 | 17 | with alembic_engine.connect() as conn: 18 | result = conn.execute(text("SELECT * FROM foo")).fetchall() 19 | assert len(result) == 1 20 | -------------------------------------------------------------------------------- /examples/test_manual_alembic_config/alembic.ini: -------------------------------------------------------------------------------- 1 | [alembic] 2 | script_location = alembic 3 | 4 | [loggers] 5 | keys = root,sqlalchemy,alembic 6 | 7 | [handlers] 8 | keys = console 9 | 10 | [formatters] 11 | keys = generic 12 | 13 | [logger_root] 14 | level = WARN 15 | handlers = console 16 | qualname = 17 | 18 | [logger_sqlalchemy] 19 | level = WARN 20 | handlers = 21 | qualname = sqlalchemy.engine 22 | 23 | [logger_alembic] 24 | level = INFO 25 | handlers = 26 | qualname = alembic 27 | 28 | [handler_console] 29 | class = StreamHandler 30 | args = (sys.stderr,) 31 | level = NOTSET 32 | formatter = generic 33 | 34 | [formatter_generic] 35 | format = %(levelname)-5.5s [%(name)s] %(message)s 36 | datefmt = %H:%M:%S 37 | -------------------------------------------------------------------------------- /examples/test_manual_alembic_config/alembic/env.py: -------------------------------------------------------------------------------- 1 | from logging.config import fileConfig 2 | 3 | from alembic import context 4 | from models import Base 5 | from sqlalchemy import engine_from_config, pool 6 | 7 | fileConfig(context.config.config_file_name) 8 | target_metadata = Base.metadata 9 | 10 | 11 | connectable = context.config.attributes.get("connection", None) 12 | 13 | if connectable is None: 14 | connectable = engine_from_config( 15 | context.config.get_section(context.config.config_ini_section), 16 | prefix="sqlalchemy.", 17 | poolclass=pool.NullPool, 18 | ) 19 | 20 | with connectable.connect() as connection: 21 | context.configure(connection=connection, target_metadata=target_metadata) 22 | 23 | with context.begin_transaction(): 24 | context.run_migrations() 25 | -------------------------------------------------------------------------------- /examples/test_manual_alembic_config/alembic/script.py.mako: -------------------------------------------------------------------------------- 1 | """${message} 2 | 3 | Revision ID: ${up_revision} 4 | Revises: ${down_revision | comma,n} 5 | Create Date: ${create_date} 6 | 7 | """ 8 | from alembic import op 9 | import sqlalchemy as sa 10 | ${imports if imports else ""} 11 | 12 | # revision identifiers, used by Alembic. 13 | revision = ${repr(up_revision)} 14 | down_revision = ${repr(down_revision)} 15 | branch_labels = ${repr(branch_labels)} 16 | depends_on = ${repr(depends_on)} 17 | 18 | 19 | def upgrade(): 20 | ${upgrades if upgrades else "pass"} 21 | 22 | 23 | def downgrade(): 24 | ${downgrades if downgrades else "pass"} 25 | -------------------------------------------------------------------------------- /examples/test_manual_alembic_config/alembic/versions/aaaaaaaaaaaa_create_foo.py: -------------------------------------------------------------------------------- 1 | import sqlalchemy as sa 2 | from alembic import op 3 | 4 | revision = "aaaaaaaaaaaa" 5 | down_revision = None 6 | branch_labels = None 7 | depends_on = None 8 | 9 | 10 | def upgrade(): 11 | op.create_table( 12 | "foo", 13 | sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), 14 | sa.Column( 15 | "created_at", 16 | sa.DateTime(timezone=True), 17 | server_default=sa.text("(CURRENT_TIMESTAMP)"), 18 | nullable=False, 19 | ), 20 | sa.PrimaryKeyConstraint("id"), 21 | ) 22 | 23 | 24 | def downgrade(): 25 | op.drop_table("foo") 26 | -------------------------------------------------------------------------------- /examples/test_manual_alembic_config/alembic/versions/bbbbbbbbbbbb_update_foo.py: -------------------------------------------------------------------------------- 1 | from alembic import op 2 | from sqlalchemy import text 3 | 4 | revision = "bbbbbbbbbbbb" 5 | down_revision = "aaaaaaaaaaaa" 6 | branch_labels = None 7 | depends_on = None 8 | 9 | 10 | def upgrade(): 11 | conn = op.get_bind() 12 | result = conn.execute(text("SELECT * FROM foo")).fetchall() 13 | assert len(result) == 0 14 | 15 | 16 | def downgrade(): 17 | pass 18 | -------------------------------------------------------------------------------- /examples/test_manual_alembic_config/conftest.py: -------------------------------------------------------------------------------- 1 | import alembic.config 2 | import pytest 3 | 4 | 5 | @pytest.fixture() 6 | def alembic_config(): 7 | config = alembic.config.Config("alembic.ini") 8 | config.set_main_option("script_location", "alembic") 9 | return config 10 | -------------------------------------------------------------------------------- /examples/test_manual_alembic_config/models.py: -------------------------------------------------------------------------------- 1 | import sqlalchemy 2 | from sqlalchemy import Column, types 3 | 4 | try: 5 | from sqlalchemy.orm import declarative_base 6 | except ImportError: 7 | from sqlalchemy.ext.declarative import declarative_base 8 | 9 | 10 | Base = declarative_base() 11 | 12 | 13 | class CreatedAt(Base): 14 | __tablename__ = "foo" 15 | 16 | id = Column(types.Integer(), autoincrement=True, primary_key=True) 17 | 18 | created_at = sqlalchemy.Column( 19 | sqlalchemy.types.DateTime(timezone=True), 20 | server_default=sqlalchemy.text("CURRENT_TIMESTAMP"), 21 | nullable=False, 22 | ) 23 | -------------------------------------------------------------------------------- /examples/test_migrate_down_before/alembic.ini: -------------------------------------------------------------------------------- 1 | [alembic] 2 | script_location = migrations 3 | 4 | [loggers] 5 | keys = root,sqlalchemy,alembic 6 | 7 | [handlers] 8 | keys = console 9 | 10 | [formatters] 11 | keys = generic 12 | 13 | [logger_root] 14 | level = WARN 15 | handlers = console 16 | qualname = 17 | 18 | [logger_sqlalchemy] 19 | level = WARN 20 | handlers = 21 | qualname = sqlalchemy.engine 22 | 23 | [logger_alembic] 24 | level = INFO 25 | handlers = 26 | qualname = alembic 27 | 28 | [handler_console] 29 | class = StreamHandler 30 | args = (sys.stderr,) 31 | level = NOTSET 32 | formatter = generic 33 | 34 | [formatter_generic] 35 | format = %(levelname)-5.5s [%(name)s] %(message)s 36 | datefmt = %H:%M:%S 37 | -------------------------------------------------------------------------------- /examples/test_migrate_down_before/conftest.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schireson/pytest-alembic/47748802f22db988fb95926189eb78ec59ad387f/examples/test_migrate_down_before/conftest.py -------------------------------------------------------------------------------- /examples/test_migrate_down_before/migrations/env.py: -------------------------------------------------------------------------------- 1 | from logging.config import fileConfig 2 | 3 | from alembic import context 4 | from models import Base 5 | from sqlalchemy import engine_from_config, pool 6 | 7 | fileConfig(context.config.config_file_name) 8 | target_metadata = Base.metadata 9 | 10 | 11 | connectable = context.config.attributes.get("connection", None) 12 | 13 | if connectable is None: 14 | connectable = engine_from_config( 15 | context.config.get_section(context.config.config_ini_section), 16 | prefix="sqlalchemy.", 17 | poolclass=pool.NullPool, 18 | ) 19 | 20 | with connectable.connect() as connection: 21 | context.configure(connection=connection, target_metadata=target_metadata) 22 | 23 | with context.begin_transaction(): 24 | context.run_migrations() 25 | -------------------------------------------------------------------------------- /examples/test_migrate_down_before/migrations/script.py.mako: -------------------------------------------------------------------------------- 1 | """${message} 2 | 3 | Revision ID: ${up_revision} 4 | Revises: ${down_revision | comma,n} 5 | Create Date: ${create_date} 6 | 7 | """ 8 | from alembic import op 9 | import sqlalchemy as sa 10 | ${imports if imports else ""} 11 | 12 | # revision identifiers, used by Alembic. 13 | revision = ${repr(up_revision)} 14 | down_revision = ${repr(down_revision)} 15 | branch_labels = ${repr(branch_labels)} 16 | depends_on = ${repr(depends_on)} 17 | 18 | 19 | def upgrade(): 20 | ${upgrades if upgrades else "pass"} 21 | 22 | 23 | def downgrade(): 24 | ${downgrades if downgrades else "pass"} 25 | -------------------------------------------------------------------------------- /examples/test_migrate_down_before/migrations/versions/aaaaaaaaaaaa_create_foo.py: -------------------------------------------------------------------------------- 1 | import sqlalchemy as sa 2 | from alembic import op 3 | 4 | revision = "aaaaaaaaaaaa" 5 | down_revision = None 6 | branch_labels = None 7 | depends_on = None 8 | 9 | 10 | def upgrade(): 11 | op.create_table( 12 | "foo", 13 | sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), 14 | sa.Column( 15 | "created_at", 16 | sa.DateTime(timezone=True), 17 | server_default=sa.text("(CURRENT_TIMESTAMP)"), 18 | nullable=False, 19 | ), 20 | sa.PrimaryKeyConstraint("id"), 21 | ) 22 | 23 | 24 | def downgrade(): 25 | op.drop_table("foo") 26 | -------------------------------------------------------------------------------- /examples/test_migrate_down_before/migrations/versions/bbbbbbbbbbbb_update_foo.py: -------------------------------------------------------------------------------- 1 | from alembic import op 2 | from sqlalchemy import text 3 | 4 | revision = "bbbbbbbbbbbb" 5 | down_revision = "aaaaaaaaaaaa" 6 | branch_labels = None 7 | depends_on = None 8 | 9 | 10 | def upgrade(): 11 | conn = op.get_bind() 12 | result = conn.execute(text("SELECT * FROM foo")).fetchall() 13 | assert len(result) == 0 14 | 15 | 16 | def downgrade(): 17 | pass 18 | -------------------------------------------------------------------------------- /examples/test_migrate_down_before/models.py: -------------------------------------------------------------------------------- 1 | import sqlalchemy 2 | from sqlalchemy import Column, types 3 | 4 | try: 5 | from sqlalchemy.orm import declarative_base 6 | except ImportError: 7 | from sqlalchemy.ext.declarative import declarative_base 8 | 9 | 10 | Base = declarative_base() 11 | 12 | 13 | class CreatedAt(Base): 14 | __tablename__ = "foo" 15 | 16 | id = Column(types.Integer(), autoincrement=True, primary_key=True) 17 | 18 | created_at = sqlalchemy.Column( 19 | sqlalchemy.types.DateTime(timezone=True), 20 | server_default=sqlalchemy.text("CURRENT_TIMESTAMP"), 21 | nullable=False, 22 | ) 23 | -------------------------------------------------------------------------------- /examples/test_migrate_down_before/test_migrations.py: -------------------------------------------------------------------------------- 1 | from sqlalchemy import text 2 | 3 | 4 | def test_migrate_down_before_specific_revision(alembic_runner, alembic_engine): 5 | alembic_runner.migrate_up_to("head") 6 | 7 | alembic_runner.migrate_down_before("aaaaaaaaaaaa") 8 | with alembic_engine.connect() as conn: 9 | result = conn.execute(text("SELECT * FROM foo")).fetchall() 10 | assert len(result) == 0 11 | -------------------------------------------------------------------------------- /examples/test_migrate_up_before/alembic.ini: -------------------------------------------------------------------------------- 1 | [alembic] 2 | script_location = migrations 3 | 4 | [loggers] 5 | keys = root,sqlalchemy,alembic 6 | 7 | [handlers] 8 | keys = console 9 | 10 | [formatters] 11 | keys = generic 12 | 13 | [logger_root] 14 | level = WARN 15 | handlers = console 16 | qualname = 17 | 18 | [logger_sqlalchemy] 19 | level = WARN 20 | handlers = 21 | qualname = sqlalchemy.engine 22 | 23 | [logger_alembic] 24 | level = INFO 25 | handlers = 26 | qualname = alembic 27 | 28 | [handler_console] 29 | class = StreamHandler 30 | args = (sys.stderr,) 31 | level = NOTSET 32 | formatter = generic 33 | 34 | [formatter_generic] 35 | format = %(levelname)-5.5s [%(name)s] %(message)s 36 | datefmt = %H:%M:%S 37 | -------------------------------------------------------------------------------- /examples/test_migrate_up_before/conftest.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schireson/pytest-alembic/47748802f22db988fb95926189eb78ec59ad387f/examples/test_migrate_up_before/conftest.py -------------------------------------------------------------------------------- /examples/test_migrate_up_before/migrations/env.py: -------------------------------------------------------------------------------- 1 | from logging.config import fileConfig 2 | 3 | from alembic import context 4 | from models import Base 5 | from sqlalchemy import engine_from_config, pool 6 | 7 | fileConfig(context.config.config_file_name) 8 | target_metadata = Base.metadata 9 | 10 | 11 | connectable = context.config.attributes.get("connection", None) 12 | 13 | if connectable is None: 14 | connectable = engine_from_config( 15 | context.config.get_section(context.config.config_ini_section), 16 | prefix="sqlalchemy.", 17 | poolclass=pool.NullPool, 18 | ) 19 | 20 | with connectable.connect() as connection: 21 | context.configure(connection=connection, target_metadata=target_metadata) 22 | 23 | with context.begin_transaction(): 24 | context.run_migrations() 25 | -------------------------------------------------------------------------------- /examples/test_migrate_up_before/migrations/script.py.mako: -------------------------------------------------------------------------------- 1 | """${message} 2 | 3 | Revision ID: ${up_revision} 4 | Revises: ${down_revision | comma,n} 5 | Create Date: ${create_date} 6 | 7 | """ 8 | from alembic import op 9 | import sqlalchemy as sa 10 | ${imports if imports else ""} 11 | 12 | # revision identifiers, used by Alembic. 13 | revision = ${repr(up_revision)} 14 | down_revision = ${repr(down_revision)} 15 | branch_labels = ${repr(branch_labels)} 16 | depends_on = ${repr(depends_on)} 17 | 18 | 19 | def upgrade(): 20 | ${upgrades if upgrades else "pass"} 21 | 22 | 23 | def downgrade(): 24 | ${downgrades if downgrades else "pass"} 25 | -------------------------------------------------------------------------------- /examples/test_migrate_up_before/migrations/versions/aaaaaaaaaaaa_create_foo.py: -------------------------------------------------------------------------------- 1 | import sqlalchemy as sa 2 | from alembic import op 3 | 4 | revision = "aaaaaaaaaaaa" 5 | down_revision = None 6 | branch_labels = None 7 | depends_on = None 8 | 9 | 10 | def upgrade(): 11 | op.create_table( 12 | "foo", 13 | sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), 14 | sa.Column( 15 | "created_at", 16 | sa.DateTime(timezone=True), 17 | server_default=sa.text("(CURRENT_TIMESTAMP)"), 18 | nullable=False, 19 | ), 20 | sa.PrimaryKeyConstraint("id"), 21 | ) 22 | 23 | 24 | def downgrade(): 25 | op.drop_table("foo") 26 | -------------------------------------------------------------------------------- /examples/test_migrate_up_before/migrations/versions/bbbbbbbbbbbb_update_foo.py: -------------------------------------------------------------------------------- 1 | from alembic import op 2 | from sqlalchemy import text 3 | 4 | revision = "bbbbbbbbbbbb" 5 | down_revision = "aaaaaaaaaaaa" 6 | branch_labels = None 7 | depends_on = None 8 | 9 | 10 | def upgrade(): 11 | conn = op.get_bind() 12 | result = conn.execute(text("SELECT * FROM foo")).fetchall() 13 | assert len(result) == 0 14 | 15 | 16 | def downgrade(): 17 | pass 18 | -------------------------------------------------------------------------------- /examples/test_migrate_up_before/models.py: -------------------------------------------------------------------------------- 1 | import sqlalchemy 2 | from sqlalchemy import Column, types 3 | 4 | try: 5 | from sqlalchemy.orm import declarative_base 6 | except ImportError: 7 | from sqlalchemy.ext.declarative import declarative_base 8 | 9 | 10 | Base = declarative_base() 11 | 12 | 13 | class CreatedAt(Base): 14 | __tablename__ = "foo" 15 | 16 | id = Column(types.Integer(), autoincrement=True, primary_key=True) 17 | 18 | created_at = sqlalchemy.Column( 19 | sqlalchemy.types.DateTime(timezone=True), 20 | server_default=sqlalchemy.text("CURRENT_TIMESTAMP"), 21 | nullable=False, 22 | ) 23 | -------------------------------------------------------------------------------- /examples/test_migrate_up_before/test_migrations.py: -------------------------------------------------------------------------------- 1 | def test_migrate_up_before_specific_revision(alembic_runner, alembic_engine): 2 | alembic_runner.migrate_up_before("bbbbbbbbbbbb") 3 | 4 | alembic_runner.insert_into("foo", {"id": 100}) 5 | 6 | table = alembic_runner.table_at_revision("foo", revision="aaaaaaaaaaaa") 7 | 8 | with alembic_engine.connect() as conn: 9 | result = conn.execute(table.select()).fetchall() 10 | assert len(result) == 1 11 | assert result[0].id == 100 12 | -------------------------------------------------------------------------------- /examples/test_migrate_up_to/alembic.ini: -------------------------------------------------------------------------------- 1 | [alembic] 2 | script_location = migrations 3 | 4 | [loggers] 5 | keys = root,sqlalchemy,alembic 6 | 7 | [handlers] 8 | keys = console 9 | 10 | [formatters] 11 | keys = generic 12 | 13 | [logger_root] 14 | level = WARN 15 | handlers = console 16 | qualname = 17 | 18 | [logger_sqlalchemy] 19 | level = WARN 20 | handlers = 21 | qualname = sqlalchemy.engine 22 | 23 | [logger_alembic] 24 | level = INFO 25 | handlers = 26 | qualname = alembic 27 | 28 | [handler_console] 29 | class = StreamHandler 30 | args = (sys.stderr,) 31 | level = NOTSET 32 | formatter = generic 33 | 34 | [formatter_generic] 35 | format = %(levelname)-5.5s [%(name)s] %(message)s 36 | datefmt = %H:%M:%S 37 | -------------------------------------------------------------------------------- /examples/test_migrate_up_to/conftest.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schireson/pytest-alembic/47748802f22db988fb95926189eb78ec59ad387f/examples/test_migrate_up_to/conftest.py -------------------------------------------------------------------------------- /examples/test_migrate_up_to/migrations/env.py: -------------------------------------------------------------------------------- 1 | from logging.config import fileConfig 2 | 3 | from alembic import context 4 | from models import Base 5 | from sqlalchemy import engine_from_config, pool 6 | 7 | fileConfig(context.config.config_file_name) 8 | target_metadata = Base.metadata 9 | 10 | 11 | connectable = context.config.attributes.get("connection", None) 12 | 13 | if connectable is None: 14 | connectable = engine_from_config( 15 | context.config.get_section(context.config.config_ini_section), 16 | prefix="sqlalchemy.", 17 | poolclass=pool.NullPool, 18 | ) 19 | 20 | with connectable.connect() as connection: 21 | context.configure(connection=connection, target_metadata=target_metadata) 22 | 23 | with context.begin_transaction(): 24 | context.run_migrations() 25 | -------------------------------------------------------------------------------- /examples/test_migrate_up_to/migrations/script.py.mako: -------------------------------------------------------------------------------- 1 | """${message} 2 | 3 | Revision ID: ${up_revision} 4 | Revises: ${down_revision | comma,n} 5 | Create Date: ${create_date} 6 | 7 | """ 8 | from alembic import op 9 | import sqlalchemy as sa 10 | ${imports if imports else ""} 11 | 12 | # revision identifiers, used by Alembic. 13 | revision = ${repr(up_revision)} 14 | down_revision = ${repr(down_revision)} 15 | branch_labels = ${repr(branch_labels)} 16 | depends_on = ${repr(depends_on)} 17 | 18 | 19 | def upgrade(): 20 | ${upgrades if upgrades else "pass"} 21 | 22 | 23 | def downgrade(): 24 | ${downgrades if downgrades else "pass"} 25 | -------------------------------------------------------------------------------- /examples/test_migrate_up_to/migrations/versions/aaaaaaaaaaaa_create_foo.py: -------------------------------------------------------------------------------- 1 | import sqlalchemy as sa 2 | from alembic import op 3 | 4 | revision = "aaaaaaaaaaaa" 5 | down_revision = None 6 | branch_labels = None 7 | depends_on = None 8 | 9 | 10 | def upgrade(): 11 | op.create_table( 12 | "foo", 13 | sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), 14 | sa.Column( 15 | "created_at", 16 | sa.DateTime(timezone=True), 17 | server_default=sa.text("(CURRENT_TIMESTAMP)"), 18 | nullable=False, 19 | ), 20 | sa.PrimaryKeyConstraint("id"), 21 | ) 22 | 23 | 24 | def downgrade(): 25 | op.drop_table("foo") 26 | -------------------------------------------------------------------------------- /examples/test_migrate_up_to/migrations/versions/bbbbbbbbbbbb_update_foo.py: -------------------------------------------------------------------------------- 1 | from alembic import op 2 | from sqlalchemy import text 3 | 4 | revision = "bbbbbbbbbbbb" 5 | down_revision = "aaaaaaaaaaaa" 6 | branch_labels = None 7 | depends_on = None 8 | 9 | 10 | def upgrade(): 11 | pass 12 | 13 | 14 | def downgrade(): 15 | conn = op.get_bind() 16 | conn.execute(text("DELETE FROM foo")) 17 | -------------------------------------------------------------------------------- /examples/test_migrate_up_to/models.py: -------------------------------------------------------------------------------- 1 | import sqlalchemy 2 | from sqlalchemy import Column, types 3 | 4 | try: 5 | from sqlalchemy.orm import declarative_base 6 | except ImportError: 7 | from sqlalchemy.ext.declarative import declarative_base 8 | 9 | 10 | Base = declarative_base() 11 | 12 | 13 | class CreatedAt(Base): 14 | __tablename__ = "foo" 15 | 16 | id = Column(types.Integer(), autoincrement=True, primary_key=True) 17 | 18 | created_at = sqlalchemy.Column( 19 | sqlalchemy.types.DateTime(timezone=True), 20 | server_default=sqlalchemy.text("CURRENT_TIMESTAMP"), 21 | nullable=False, 22 | ) 23 | -------------------------------------------------------------------------------- /examples/test_migrate_up_to/test_migrations.py: -------------------------------------------------------------------------------- 1 | from sqlalchemy import text 2 | 3 | 4 | def test_migrate_up_to_specific_revision(alembic_runner, alembic_engine): 5 | alembic_runner.migrate_up_to("aaaaaaaaaaaa") 6 | 7 | with alembic_engine.begin() as conn: 8 | conn.execute(text("INSERT INTO foo (id) VALUES (100)")) 9 | 10 | alembic_runner.roundtrip_next_revision() 11 | 12 | with alembic_engine.connect() as conn: 13 | result = conn.execute(text("SELECT * FROM foo")).fetchall() 14 | assert len(result) == 0 15 | 16 | # There should be no migrations left 17 | result = alembic_runner.roundtrip_next_revision() 18 | assert result is None 19 | -------------------------------------------------------------------------------- /examples/test_minimum_downgrade_revision/alembic.ini: -------------------------------------------------------------------------------- 1 | [alembic] 2 | script_location = migrations 3 | 4 | [loggers] 5 | keys = root,sqlalchemy,alembic 6 | 7 | [handlers] 8 | keys = console 9 | 10 | [formatters] 11 | keys = generic 12 | 13 | [logger_root] 14 | level = WARN 15 | handlers = console 16 | qualname = 17 | 18 | [logger_sqlalchemy] 19 | level = WARN 20 | handlers = 21 | qualname = sqlalchemy.engine 22 | 23 | [logger_alembic] 24 | level = INFO 25 | handlers = 26 | qualname = alembic 27 | 28 | [handler_console] 29 | class = StreamHandler 30 | args = (sys.stderr,) 31 | level = NOTSET 32 | formatter = generic 33 | 34 | [formatter_generic] 35 | format = %(levelname)-5.5s [%(name)s] %(message)s 36 | datefmt = %H:%M:%S 37 | -------------------------------------------------------------------------------- /examples/test_minimum_downgrade_revision/conftest.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | from pytest_mock_resources import create_postgres_fixture 3 | 4 | alembic_engine = create_postgres_fixture() 5 | 6 | 7 | @pytest.fixture() 8 | def alembic_config(): 9 | return {"minimum_downgrade_revision": "cccccccccccc"} 10 | -------------------------------------------------------------------------------- /examples/test_minimum_downgrade_revision/migrations/env.py: -------------------------------------------------------------------------------- 1 | from logging.config import fileConfig 2 | 3 | from alembic import context 4 | from models import Base 5 | from sqlalchemy import engine_from_config, pool 6 | 7 | fileConfig(context.config.config_file_name) 8 | target_metadata = Base.metadata 9 | 10 | 11 | connectable = context.config.attributes.get("connection", None) 12 | 13 | if connectable is None: 14 | connectable = engine_from_config( 15 | context.config.get_section(context.config.config_ini_section), 16 | prefix="sqlalchemy.", 17 | poolclass=pool.NullPool, 18 | ) 19 | 20 | with connectable.connect() as connection: 21 | context.configure(connection=connection, target_metadata=target_metadata) 22 | 23 | with context.begin_transaction(): 24 | context.run_migrations() 25 | -------------------------------------------------------------------------------- /examples/test_minimum_downgrade_revision/migrations/script.py.mako: -------------------------------------------------------------------------------- 1 | """${message} 2 | 3 | Revision ID: ${up_revision} 4 | Revises: ${down_revision | comma,n} 5 | Create Date: ${create_date} 6 | 7 | """ 8 | from alembic import op 9 | import sqlalchemy as sa 10 | ${imports if imports else ""} 11 | 12 | # revision identifiers, used by Alembic. 13 | revision = ${repr(up_revision)} 14 | down_revision = ${repr(down_revision)} 15 | branch_labels = ${repr(branch_labels)} 16 | depends_on = ${repr(depends_on)} 17 | 18 | 19 | def upgrade(): 20 | ${upgrades if upgrades else "pass"} 21 | 22 | 23 | def downgrade(): 24 | ${downgrades if downgrades else "pass"} 25 | -------------------------------------------------------------------------------- /examples/test_minimum_downgrade_revision/migrations/versions/aaaaaaaaaaaa_create_foo.py: -------------------------------------------------------------------------------- 1 | import sqlalchemy as sa 2 | from alembic import op 3 | 4 | revision = "aaaaaaaaaaaa" 5 | down_revision = None 6 | branch_labels = None 7 | depends_on = None 8 | 9 | 10 | def upgrade(): 11 | op.create_table( 12 | "foo", 13 | sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), 14 | sa.PrimaryKeyConstraint("id"), 15 | ) 16 | 17 | 18 | def downgrade(): 19 | op.drop_table("foo") 20 | -------------------------------------------------------------------------------- /examples/test_minimum_downgrade_revision/migrations/versions/bbbbbbbbbbbb_create_foo.py: -------------------------------------------------------------------------------- 1 | from alembic import op 2 | 3 | revision = "bbbbbbbbbbbb" 4 | down_revision = "aaaaaaaaaaaa" 5 | branch_labels = None 6 | depends_on = None 7 | 8 | 9 | def upgrade(): 10 | op.get_bind() 11 | op.execute("DELETE FROM foo") 12 | 13 | 14 | def downgrade(): 15 | msg = "Cannot downgrade here!" 16 | raise ValueError(msg) 17 | -------------------------------------------------------------------------------- /examples/test_minimum_downgrade_revision/migrations/versions/cccccccccccc_create_foo.py: -------------------------------------------------------------------------------- 1 | import sqlalchemy as sa 2 | from alembic import op 3 | 4 | revision = "cccccccccccc" 5 | down_revision = "bbbbbbbbbbbb" 6 | branch_labels = None 7 | depends_on = None 8 | 9 | 10 | def upgrade(): 11 | op.add_column("foo", sa.Column("foo_id", sa.Integer(), server_default="9")) 12 | 13 | 14 | def downgrade(): 15 | op.drop_column("foo", "foo_id") 16 | -------------------------------------------------------------------------------- /examples/test_minimum_downgrade_revision/migrations/versions/dddddddddddd_create_foo.py: -------------------------------------------------------------------------------- 1 | import sqlalchemy as sa 2 | from alembic import op 3 | 4 | revision = "dddddddddddd" 5 | down_revision = "cccccccccccc" 6 | branch_labels = None 7 | depends_on = None 8 | 9 | 10 | def upgrade(): 11 | op.add_column("foo", sa.Column("bar_id", sa.Integer(), server_default="9")) 12 | 13 | 14 | def downgrade(): 15 | op.drop_column("foo", "bar_id") 16 | -------------------------------------------------------------------------------- /examples/test_minimum_downgrade_revision/models.py: -------------------------------------------------------------------------------- 1 | from sqlalchemy import Column, types 2 | 3 | try: 4 | from sqlalchemy.orm import declarative_base 5 | except ImportError: 6 | from sqlalchemy.ext.declarative import declarative_base 7 | 8 | 9 | Base = declarative_base() 10 | 11 | 12 | class CreatedAt(Base): 13 | __tablename__ = "foo" 14 | 15 | id = Column(types.Integer(), autoincrement=True, primary_key=True) 16 | foo_id = Column(types.Integer()) 17 | bar_id = Column(types.Integer()) 18 | -------------------------------------------------------------------------------- /examples/test_minimum_downgrade_revision/setup.cfg: -------------------------------------------------------------------------------- 1 | [tool:pytest] 2 | pytest_alembic_include_experimental = downgrade_leaves_no_trace 3 | -------------------------------------------------------------------------------- /examples/test_multiple_schemata/alembic.ini: -------------------------------------------------------------------------------- 1 | [alembic] 2 | script_location = migrations 3 | 4 | [loggers] 5 | keys = root,sqlalchemy,alembic 6 | 7 | [handlers] 8 | keys = console 9 | 10 | [formatters] 11 | keys = generic 12 | 13 | [logger_root] 14 | level = WARN 15 | handlers = console 16 | qualname = 17 | 18 | [logger_sqlalchemy] 19 | level = WARN 20 | handlers = 21 | qualname = sqlalchemy.engine 22 | 23 | [logger_alembic] 24 | level = INFO 25 | handlers = 26 | qualname = alembic 27 | 28 | [handler_console] 29 | class = StreamHandler 30 | args = (sys.stderr,) 31 | level = NOTSET 32 | formatter = generic 33 | 34 | [formatter_generic] 35 | format = %(levelname)-5.5s [%(name)s] %(message)s 36 | datefmt = %H:%M:%S 37 | -------------------------------------------------------------------------------- /examples/test_multiple_schemata/alembic2.ini: -------------------------------------------------------------------------------- 1 | [alembic] 2 | script_location = migrations2 3 | 4 | [loggers] 5 | keys = root,sqlalchemy,alembic 6 | 7 | [handlers] 8 | keys = console 9 | 10 | [formatters] 11 | keys = generic 12 | 13 | [logger_root] 14 | level = WARN 15 | handlers = console 16 | qualname = 17 | 18 | [logger_sqlalchemy] 19 | level = WARN 20 | handlers = 21 | qualname = sqlalchemy.engine 22 | 23 | [logger_alembic] 24 | level = INFO 25 | handlers = 26 | qualname = alembic 27 | 28 | [handler_console] 29 | class = StreamHandler 30 | args = (sys.stderr,) 31 | level = NOTSET 32 | formatter = generic 33 | 34 | [formatter_generic] 35 | format = %(levelname)-5.5s [%(name)s] %(message)s 36 | datefmt = %H:%M:%S 37 | -------------------------------------------------------------------------------- /examples/test_multiple_schemata/migrations/env.py: -------------------------------------------------------------------------------- 1 | from logging.config import fileConfig 2 | 3 | from alembic import context 4 | from models import Base 5 | from sqlalchemy import engine_from_config, pool 6 | 7 | fileConfig(context.config.config_file_name) 8 | target_metadata = Base.metadata 9 | 10 | 11 | connectable = context.config.attributes.get("connection", None) 12 | 13 | if connectable is None: 14 | connectable = engine_from_config( 15 | context.config.get_section(context.config.config_ini_section), 16 | prefix="sqlalchemy.", 17 | poolclass=pool.NullPool, 18 | ) 19 | 20 | with connectable.connect() as connection: 21 | context.configure(connection=connection, target_metadata=target_metadata) 22 | 23 | with context.begin_transaction(): 24 | context.run_migrations() 25 | -------------------------------------------------------------------------------- /examples/test_multiple_schemata/migrations/script.py.mako: -------------------------------------------------------------------------------- 1 | """${message} 2 | 3 | Revision ID: ${up_revision} 4 | Revises: ${down_revision | comma,n} 5 | Create Date: ${create_date} 6 | 7 | """ 8 | from alembic import op 9 | import sqlalchemy as sa 10 | ${imports if imports else ""} 11 | 12 | # revision identifiers, used by Alembic. 13 | revision = ${repr(up_revision)} 14 | down_revision = ${repr(down_revision)} 15 | branch_labels = ${repr(branch_labels)} 16 | depends_on = ${repr(depends_on)} 17 | 18 | 19 | def upgrade(): 20 | ${upgrades if upgrades else "pass"} 21 | 22 | 23 | def downgrade(): 24 | ${downgrades if downgrades else "pass"} 25 | -------------------------------------------------------------------------------- /examples/test_multiple_schemata/migrations/versions/aaaaaaaaaaaa_create_foo.py: -------------------------------------------------------------------------------- 1 | import sqlalchemy as sa 2 | from alembic import op 3 | 4 | revision = "aaaaaaaaaaaa" 5 | down_revision = None 6 | branch_labels = None 7 | depends_on = None 8 | 9 | 10 | def upgrade(): 11 | op.create_table( 12 | "foo", 13 | sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), 14 | sa.Column( 15 | "created_at", 16 | sa.DateTime(timezone=True), 17 | server_default=sa.text("(CURRENT_TIMESTAMP)"), 18 | nullable=False, 19 | ), 20 | sa.PrimaryKeyConstraint("id"), 21 | ) 22 | 23 | 24 | def downgrade(): 25 | op.drop_table("foo") 26 | -------------------------------------------------------------------------------- /examples/test_multiple_schemata/migrations/versions/bbbbbbbbbbbb_update_foo.py: -------------------------------------------------------------------------------- 1 | from alembic import op 2 | from sqlalchemy import text 3 | 4 | revision = "bbbbbbbbbbbb" 5 | down_revision = "aaaaaaaaaaaa" 6 | branch_labels = None 7 | depends_on = None 8 | 9 | 10 | def upgrade(): 11 | conn = op.get_bind() 12 | result = conn.execute(text("SELECT * FROM foo")).fetchall() 13 | assert len(result) == 0 14 | 15 | 16 | def downgrade(): 17 | pass 18 | -------------------------------------------------------------------------------- /examples/test_multiple_schemata/migrations2/env.py: -------------------------------------------------------------------------------- 1 | from logging.config import fileConfig 2 | 3 | from alembic import context 4 | from models2 import Base 5 | from sqlalchemy import engine_from_config, pool 6 | 7 | fileConfig(context.config.config_file_name) 8 | target_metadata = Base.metadata 9 | 10 | 11 | connectable = context.config.attributes.get("connection", None) 12 | 13 | if connectable is None: 14 | connectable = engine_from_config( 15 | context.config.get_section(context.config.config_ini_section), 16 | prefix="sqlalchemy.", 17 | poolclass=pool.NullPool, 18 | ) 19 | 20 | with connectable.connect() as connection: 21 | context.configure(connection=connection, target_metadata=target_metadata) 22 | 23 | with context.begin_transaction(): 24 | context.run_migrations() 25 | -------------------------------------------------------------------------------- /examples/test_multiple_schemata/migrations2/script.py.mako: -------------------------------------------------------------------------------- 1 | """${message} 2 | 3 | Revision ID: ${up_revision} 4 | Revises: ${down_revision | comma,n} 5 | Create Date: ${create_date} 6 | 7 | """ 8 | from alembic import op 9 | import sqlalchemy as sa 10 | ${imports if imports else ""} 11 | 12 | # revision identifiers, used by Alembic. 13 | revision = ${repr(up_revision)} 14 | down_revision = ${repr(down_revision)} 15 | branch_labels = ${repr(branch_labels)} 16 | depends_on = ${repr(depends_on)} 17 | 18 | 19 | def upgrade(): 20 | ${upgrades if upgrades else "pass"} 21 | 22 | 23 | def downgrade(): 24 | ${downgrades if downgrades else "pass"} 25 | -------------------------------------------------------------------------------- /examples/test_multiple_schemata/migrations2/versions/aaaaaaaaaaaa_create_foo.py: -------------------------------------------------------------------------------- 1 | import sqlalchemy as sa 2 | from alembic import op 3 | 4 | revision = "aaaaaaaaaaaa" 5 | down_revision = None 6 | branch_labels = None 7 | depends_on = None 8 | 9 | 10 | def upgrade(): 11 | op.create_table( 12 | "foo", 13 | sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), 14 | sa.Column( 15 | "created_at", 16 | sa.DateTime(timezone=True), 17 | server_default=sa.text("(CURRENT_TIMESTAMP)"), 18 | nullable=False, 19 | ), 20 | sa.PrimaryKeyConstraint("id"), 21 | ) 22 | 23 | 24 | def downgrade(): 25 | op.drop_table("foo") 26 | -------------------------------------------------------------------------------- /examples/test_multiple_schemata/migrations2/versions/bbbbbbbbbbbb_update_foo.py: -------------------------------------------------------------------------------- 1 | from alembic import op 2 | from sqlalchemy import text 3 | 4 | revision = "bbbbbbbbbbbb" 5 | down_revision = "aaaaaaaaaaaa" 6 | branch_labels = None 7 | depends_on = None 8 | 9 | 10 | def upgrade(): 11 | conn = op.get_bind() 12 | result = conn.execute(text("SELECT * FROM foo")).fetchall() 13 | assert len(result) == 0 14 | 15 | 16 | def downgrade(): 17 | pass 18 | -------------------------------------------------------------------------------- /examples/test_multiple_schemata/models.py: -------------------------------------------------------------------------------- 1 | import sqlalchemy 2 | from sqlalchemy import Column, types 3 | 4 | try: 5 | from sqlalchemy.orm import declarative_base 6 | except ImportError: 7 | from sqlalchemy.ext.declarative import declarative_base 8 | 9 | 10 | Base = declarative_base() 11 | 12 | 13 | class CreatedAt(Base): 14 | __tablename__ = "foo" 15 | 16 | id = Column(types.Integer(), autoincrement=True, primary_key=True) 17 | 18 | created_at = sqlalchemy.Column( 19 | sqlalchemy.types.DateTime(timezone=True), 20 | server_default=sqlalchemy.text("CURRENT_TIMESTAMP"), 21 | nullable=False, 22 | ) 23 | -------------------------------------------------------------------------------- /examples/test_multiple_schemata/models2.py: -------------------------------------------------------------------------------- 1 | import sqlalchemy 2 | from sqlalchemy import Column, types 3 | 4 | try: 5 | from sqlalchemy.orm import declarative_base 6 | except ImportError: 7 | from sqlalchemy.ext.declarative import declarative_base 8 | 9 | 10 | Base = declarative_base() 11 | 12 | 13 | class CreatedAt(Base): 14 | __tablename__ = "foo" 15 | 16 | id = Column(types.Integer(), autoincrement=True, primary_key=True) 17 | 18 | created_at = sqlalchemy.Column( 19 | sqlalchemy.types.DateTime(timezone=True), 20 | server_default=sqlalchemy.text("CURRENT_TIMESTAMP"), 21 | nullable=False, 22 | ) 23 | -------------------------------------------------------------------------------- /examples/test_no_data/alembic.ini: -------------------------------------------------------------------------------- 1 | [alembic] 2 | script_location = migrations 3 | 4 | [loggers] 5 | keys = root,sqlalchemy,alembic 6 | 7 | [handlers] 8 | keys = console 9 | 10 | [formatters] 11 | keys = generic 12 | 13 | [logger_root] 14 | level = WARN 15 | handlers = console 16 | qualname = 17 | 18 | [logger_sqlalchemy] 19 | level = WARN 20 | handlers = 21 | qualname = sqlalchemy.engine 22 | 23 | [logger_alembic] 24 | level = INFO 25 | handlers = 26 | qualname = alembic 27 | 28 | [handler_console] 29 | class = StreamHandler 30 | args = (sys.stderr,) 31 | level = NOTSET 32 | formatter = generic 33 | 34 | [formatter_generic] 35 | format = %(levelname)-5.5s [%(name)s] %(message)s 36 | datefmt = %H:%M:%S 37 | -------------------------------------------------------------------------------- /examples/test_no_data/conftest.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schireson/pytest-alembic/47748802f22db988fb95926189eb78ec59ad387f/examples/test_no_data/conftest.py -------------------------------------------------------------------------------- /examples/test_no_data/migrations/env.py: -------------------------------------------------------------------------------- 1 | from logging.config import fileConfig 2 | 3 | from alembic import context 4 | from models import Base 5 | from sqlalchemy import engine_from_config, pool 6 | 7 | fileConfig(context.config.config_file_name) 8 | target_metadata = Base.metadata 9 | 10 | 11 | connectable = context.config.attributes.get("connection", None) 12 | 13 | if connectable is None: 14 | connectable = engine_from_config( 15 | context.config.get_section(context.config.config_ini_section), 16 | prefix="sqlalchemy.", 17 | poolclass=pool.NullPool, 18 | ) 19 | 20 | with connectable.connect() as connection: 21 | context.configure(connection=connection, target_metadata=target_metadata) 22 | 23 | with context.begin_transaction(): 24 | context.run_migrations() 25 | -------------------------------------------------------------------------------- /examples/test_no_data/migrations/script.py.mako: -------------------------------------------------------------------------------- 1 | """${message} 2 | 3 | Revision ID: ${up_revision} 4 | Revises: ${down_revision | comma,n} 5 | Create Date: ${create_date} 6 | 7 | """ 8 | from alembic import op 9 | import sqlalchemy as sa 10 | ${imports if imports else ""} 11 | 12 | # revision identifiers, used by Alembic. 13 | revision = ${repr(up_revision)} 14 | down_revision = ${repr(down_revision)} 15 | branch_labels = ${repr(branch_labels)} 16 | depends_on = ${repr(depends_on)} 17 | 18 | 19 | def upgrade(): 20 | ${upgrades if upgrades else "pass"} 21 | 22 | 23 | def downgrade(): 24 | ${downgrades if downgrades else "pass"} 25 | -------------------------------------------------------------------------------- /examples/test_no_data/migrations/versions/aaaaaaaaaaaa_create_foo.py: -------------------------------------------------------------------------------- 1 | import sqlalchemy as sa 2 | from alembic import op 3 | 4 | revision = "aaaaaaaaaaaa" 5 | down_revision = None 6 | branch_labels = None 7 | depends_on = None 8 | 9 | 10 | def upgrade(): 11 | op.create_table( 12 | "foo", 13 | sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), 14 | sa.Column( 15 | "created_at", 16 | sa.DateTime(timezone=True), 17 | server_default=sa.text("(CURRENT_TIMESTAMP)"), 18 | nullable=False, 19 | ), 20 | sa.PrimaryKeyConstraint("id"), 21 | ) 22 | 23 | 24 | def downgrade(): 25 | op.drop_table("foo") 26 | -------------------------------------------------------------------------------- /examples/test_no_data/migrations/versions/bbbbbbbbbbbb_update_foo.py: -------------------------------------------------------------------------------- 1 | from alembic import op 2 | from sqlalchemy import text 3 | 4 | revision = "bbbbbbbbbbbb" 5 | down_revision = "aaaaaaaaaaaa" 6 | branch_labels = None 7 | depends_on = None 8 | 9 | 10 | def upgrade(): 11 | conn = op.get_bind() 12 | result = conn.execute(text("SELECT * FROM foo")).fetchall() 13 | assert len(result) == 0 14 | 15 | 16 | def downgrade(): 17 | pass 18 | -------------------------------------------------------------------------------- /examples/test_no_data/models.py: -------------------------------------------------------------------------------- 1 | import sqlalchemy 2 | from sqlalchemy import Column, types 3 | 4 | try: 5 | from sqlalchemy.orm import declarative_base 6 | except ImportError: 7 | from sqlalchemy.ext.declarative import declarative_base 8 | 9 | 10 | Base = declarative_base() 11 | 12 | 13 | class CreatedAt(Base): 14 | __tablename__ = "foo" 15 | 16 | id = Column(types.Integer(), autoincrement=True, primary_key=True) 17 | 18 | created_at = sqlalchemy.Column( 19 | sqlalchemy.types.DateTime(timezone=True), 20 | server_default=sqlalchemy.text("CURRENT_TIMESTAMP"), 21 | nullable=False, 22 | ) 23 | -------------------------------------------------------------------------------- /examples/test_process_revision_directives/alembic.ini: -------------------------------------------------------------------------------- 1 | [alembic] 2 | script_location = migrations 3 | 4 | [loggers] 5 | keys = root,sqlalchemy,alembic 6 | 7 | [handlers] 8 | keys = console 9 | 10 | [formatters] 11 | keys = generic 12 | 13 | [logger_root] 14 | level = WARN 15 | handlers = console 16 | qualname = 17 | 18 | [logger_sqlalchemy] 19 | level = WARN 20 | handlers = 21 | qualname = sqlalchemy.engine 22 | 23 | [logger_alembic] 24 | level = INFO 25 | handlers = 26 | qualname = alembic 27 | 28 | [handler_console] 29 | class = StreamHandler 30 | args = (sys.stderr,) 31 | level = NOTSET 32 | formatter = generic 33 | 34 | [formatter_generic] 35 | format = %(levelname)-5.5s [%(name)s] %(message)s 36 | datefmt = %H:%M:%S 37 | -------------------------------------------------------------------------------- /examples/test_process_revision_directives/conftest.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | 3 | 4 | def err(*_): 5 | msg = "foo" 6 | raise Exception(msg) # noqa: TRY 7 | 8 | 9 | @pytest.fixture() 10 | def alembic_config(): 11 | return { 12 | "process_revision_directives": err, 13 | } 14 | -------------------------------------------------------------------------------- /examples/test_process_revision_directives/migrations/env.py: -------------------------------------------------------------------------------- 1 | from logging.config import fileConfig 2 | 3 | from alembic import context 4 | from models import Base 5 | from sqlalchemy import engine_from_config, pool 6 | 7 | fileConfig(context.config.config_file_name) 8 | target_metadata = Base.metadata 9 | 10 | 11 | connectable = context.config.attributes.get("connection", None) 12 | 13 | if connectable is None: 14 | connectable = engine_from_config( 15 | context.config.get_section(context.config.config_ini_section), 16 | prefix="sqlalchemy.", 17 | poolclass=pool.NullPool, 18 | ) 19 | 20 | with connectable.connect() as connection: 21 | context.configure(connection=connection, target_metadata=target_metadata) 22 | 23 | with context.begin_transaction(): 24 | context.run_migrations() 25 | -------------------------------------------------------------------------------- /examples/test_process_revision_directives/migrations/script.py.mako: -------------------------------------------------------------------------------- 1 | """${message} 2 | 3 | Revision ID: ${up_revision} 4 | Revises: ${down_revision | comma,n} 5 | Create Date: ${create_date} 6 | 7 | """ 8 | from alembic import op 9 | import sqlalchemy as sa 10 | ${imports if imports else ""} 11 | 12 | # revision identifiers, used by Alembic. 13 | revision = ${repr(up_revision)} 14 | down_revision = ${repr(down_revision)} 15 | branch_labels = ${repr(branch_labels)} 16 | depends_on = ${repr(depends_on)} 17 | 18 | 19 | def upgrade(): 20 | ${upgrades if upgrades else "pass"} 21 | 22 | 23 | def downgrade(): 24 | ${downgrades if downgrades else "pass"} 25 | -------------------------------------------------------------------------------- /examples/test_process_revision_directives/migrations/versions/aaaaaaaaaaaa_create_foo.py: -------------------------------------------------------------------------------- 1 | import sqlalchemy as sa 2 | from alembic import op 3 | 4 | revision = "aaaaaaaaaaaa" 5 | down_revision = None 6 | branch_labels = None 7 | depends_on = None 8 | 9 | 10 | def upgrade(): 11 | op.create_table( 12 | "foo", 13 | sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), 14 | sa.Column( 15 | "created_at", 16 | sa.DateTime(timezone=True), 17 | server_default=sa.text("(CURRENT_TIMESTAMP)"), 18 | nullable=False, 19 | ), 20 | sa.PrimaryKeyConstraint("id"), 21 | ) 22 | 23 | 24 | def downgrade(): 25 | op.drop_table("foo") 26 | -------------------------------------------------------------------------------- /examples/test_process_revision_directives/migrations/versions/bbbbbbbbbbbb_update_foo.py: -------------------------------------------------------------------------------- 1 | from alembic import op 2 | from sqlalchemy import text 3 | 4 | revision = "bbbbbbbbbbbb" 5 | down_revision = "aaaaaaaaaaaa" 6 | branch_labels = None 7 | depends_on = None 8 | 9 | 10 | def upgrade(): 11 | pass 12 | 13 | 14 | def downgrade(): 15 | conn = op.get_bind() 16 | conn.execute(text("DELETE FROM foo")) 17 | -------------------------------------------------------------------------------- /examples/test_process_revision_directives/models.py: -------------------------------------------------------------------------------- 1 | import sqlalchemy 2 | from sqlalchemy import Column, types 3 | 4 | try: 5 | from sqlalchemy.orm import declarative_base 6 | except ImportError: 7 | from sqlalchemy.ext.declarative import declarative_base 8 | 9 | 10 | Base = declarative_base() 11 | 12 | 13 | class CreatedAt(Base): 14 | __tablename__ = "foo" 15 | 16 | id = Column(types.Integer(), autoincrement=True, primary_key=True) 17 | 18 | created_at = sqlalchemy.Column( 19 | sqlalchemy.types.DateTime(timezone=True), 20 | server_default=sqlalchemy.text("CURRENT_TIMESTAMP"), 21 | nullable=False, 22 | ) 23 | -------------------------------------------------------------------------------- /examples/test_pytest_alembic_tests_path/alembic.ini: -------------------------------------------------------------------------------- 1 | [alembic] 2 | script_location = alembic 3 | 4 | [loggers] 5 | keys = root,sqlalchemy,alembic 6 | 7 | [handlers] 8 | keys = console 9 | 10 | [formatters] 11 | keys = generic 12 | 13 | [logger_root] 14 | level = WARN 15 | handlers = console 16 | qualname = 17 | 18 | [logger_sqlalchemy] 19 | level = WARN 20 | handlers = 21 | qualname = sqlalchemy.engine 22 | 23 | [logger_alembic] 24 | level = INFO 25 | handlers = 26 | qualname = alembic 27 | 28 | [handler_console] 29 | class = StreamHandler 30 | args = (sys.stderr,) 31 | level = NOTSET 32 | formatter = generic 33 | 34 | [formatter_generic] 35 | format = %(levelname)-5.5s [%(name)s] %(message)s 36 | datefmt = %H:%M:%S 37 | -------------------------------------------------------------------------------- /examples/test_pytest_alembic_tests_path/alembic/env.py: -------------------------------------------------------------------------------- 1 | from logging.config import fileConfig 2 | 3 | from alembic import context 4 | from models import Base 5 | from sqlalchemy import engine_from_config, pool 6 | 7 | fileConfig(context.config.config_file_name) 8 | target_metadata = Base.metadata 9 | 10 | 11 | connectable = context.config.attributes.get("connection", None) 12 | 13 | if connectable is None: 14 | connectable = engine_from_config( 15 | context.config.get_section(context.config.config_ini_section), 16 | prefix="sqlalchemy.", 17 | poolclass=pool.NullPool, 18 | ) 19 | 20 | with connectable.connect() as connection: 21 | context.configure(connection=connection, target_metadata=target_metadata) 22 | 23 | with context.begin_transaction(): 24 | context.run_migrations() 25 | -------------------------------------------------------------------------------- /examples/test_pytest_alembic_tests_path/alembic/script.py.mako: -------------------------------------------------------------------------------- 1 | """${message} 2 | 3 | Revision ID: ${up_revision} 4 | Revises: ${down_revision | comma,n} 5 | Create Date: ${create_date} 6 | 7 | """ 8 | from alembic import op 9 | import sqlalchemy as sa 10 | ${imports if imports else ""} 11 | 12 | # revision identifiers, used by Alembic. 13 | revision = ${repr(up_revision)} 14 | down_revision = ${repr(down_revision)} 15 | branch_labels = ${repr(branch_labels)} 16 | depends_on = ${repr(depends_on)} 17 | 18 | 19 | def upgrade(): 20 | ${upgrades if upgrades else "pass"} 21 | 22 | 23 | def downgrade(): 24 | ${downgrades if downgrades else "pass"} 25 | -------------------------------------------------------------------------------- /examples/test_pytest_alembic_tests_path/alembic/versions/aaaaaaaaaaaa_create_foo.py: -------------------------------------------------------------------------------- 1 | import sqlalchemy as sa 2 | from alembic import op 3 | 4 | revision = "aaaaaaaaaaaa" 5 | down_revision = None 6 | branch_labels = None 7 | depends_on = None 8 | 9 | 10 | def upgrade(): 11 | op.create_table( 12 | "foo", 13 | sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), 14 | sa.Column( 15 | "created_at", 16 | sa.DateTime(timezone=True), 17 | server_default=sa.text("(CURRENT_TIMESTAMP)"), 18 | nullable=False, 19 | ), 20 | sa.PrimaryKeyConstraint("id"), 21 | ) 22 | 23 | 24 | def downgrade(): 25 | op.drop_table("foo") 26 | -------------------------------------------------------------------------------- /examples/test_pytest_alembic_tests_path/alembic/versions/bbbbbbbbbbbb_update_foo.py: -------------------------------------------------------------------------------- 1 | from alembic import op 2 | from sqlalchemy import text 3 | 4 | revision = "bbbbbbbbbbbb" 5 | down_revision = "aaaaaaaaaaaa" 6 | branch_labels = None 7 | depends_on = None 8 | 9 | 10 | def upgrade(): 11 | conn = op.get_bind() 12 | result = conn.execute(text("SELECT * FROM foo")).fetchall() 13 | assert len(result) == 0 14 | 15 | 16 | def downgrade(): 17 | pass 18 | -------------------------------------------------------------------------------- /examples/test_pytest_alembic_tests_path/models/__init__.py: -------------------------------------------------------------------------------- 1 | import sqlalchemy 2 | from sqlalchemy import Column, types 3 | 4 | try: 5 | from sqlalchemy.orm import declarative_base 6 | except ImportError: 7 | from sqlalchemy.ext.declarative import declarative_base 8 | 9 | 10 | Base = declarative_base() 11 | 12 | 13 | class CreatedAt(Base): 14 | __tablename__ = "foo" 15 | 16 | id = Column(types.Integer(), autoincrement=True, primary_key=True) 17 | 18 | created_at = sqlalchemy.Column( 19 | sqlalchemy.types.DateTime(timezone=True), 20 | server_default=sqlalchemy.text("CURRENT_TIMESTAMP"), 21 | nullable=False, 22 | ) 23 | -------------------------------------------------------------------------------- /examples/test_pytest_alembic_tests_path/pytest.ini: -------------------------------------------------------------------------------- 1 | [pytest] 2 | pytest_alembic_tests_path = tests_/test/conftest.py 3 | -------------------------------------------------------------------------------- /examples/test_pytest_alembic_tests_path/tests_/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schireson/pytest-alembic/47748802f22db988fb95926189eb78ec59ad387f/examples/test_pytest_alembic_tests_path/tests_/__init__.py -------------------------------------------------------------------------------- /examples/test_pytest_alembic_tests_path/tests_/conftest.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | 3 | 4 | @pytest.fixture() 5 | def alembic_engine(): # noqa: PT 6 | raise 7 | -------------------------------------------------------------------------------- /examples/test_pytest_alembic_tests_path/tests_/test/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schireson/pytest-alembic/47748802f22db988fb95926189eb78ec59ad387f/examples/test_pytest_alembic_tests_path/tests_/test/__init__.py -------------------------------------------------------------------------------- /examples/test_pytest_alembic_tests_path/tests_/test/conftest.py: -------------------------------------------------------------------------------- 1 | from pytest_mock_resources import create_postgres_fixture 2 | 3 | alembic_engine = create_postgres_fixture() 4 | -------------------------------------------------------------------------------- /examples/test_schema_revision_data/alembic.ini: -------------------------------------------------------------------------------- 1 | [alembic] 2 | script_location = migrations 3 | 4 | [loggers] 5 | keys = root,sqlalchemy,alembic 6 | 7 | [handlers] 8 | keys = console 9 | 10 | [formatters] 11 | keys = generic 12 | 13 | [logger_root] 14 | level = WARN 15 | handlers = console 16 | qualname = 17 | 18 | [logger_sqlalchemy] 19 | level = WARN 20 | handlers = 21 | qualname = sqlalchemy.engine 22 | 23 | [logger_alembic] 24 | level = INFO 25 | handlers = 26 | qualname = alembic 27 | 28 | [handler_console] 29 | class = StreamHandler 30 | args = (sys.stderr,) 31 | level = NOTSET 32 | formatter = generic 33 | 34 | [formatter_generic] 35 | format = %(levelname)-5.5s [%(name)s] %(message)s 36 | datefmt = %H:%M:%S 37 | -------------------------------------------------------------------------------- /examples/test_schema_revision_data/conftest.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | from pytest_mock_resources import create_postgres_fixture 3 | 4 | alembic_engine = create_postgres_fixture() 5 | 6 | 7 | @pytest.fixture() 8 | def alembic_config(): 9 | return {"before_revision_data": {"bbbbbbbbbbbb": {"__tablename__": "meow.foo", "id": 9}}} 10 | -------------------------------------------------------------------------------- /examples/test_schema_revision_data/migrations/env.py: -------------------------------------------------------------------------------- 1 | from logging.config import fileConfig 2 | 3 | from alembic import context 4 | from models import Base 5 | from sqlalchemy import engine_from_config, pool 6 | 7 | fileConfig(context.config.config_file_name) 8 | target_metadata = Base.metadata 9 | 10 | 11 | connectable = context.config.attributes.get("connection", None) 12 | 13 | if connectable is None: 14 | connectable = engine_from_config( 15 | context.config.get_section(context.config.config_ini_section), 16 | prefix="sqlalchemy.", 17 | poolclass=pool.NullPool, 18 | ) 19 | 20 | with connectable.connect() as connection: 21 | context.configure(connection=connection, target_metadata=target_metadata) 22 | 23 | with context.begin_transaction(): 24 | context.run_migrations() 25 | -------------------------------------------------------------------------------- /examples/test_schema_revision_data/migrations/script.py.mako: -------------------------------------------------------------------------------- 1 | """${message} 2 | 3 | Revision ID: ${up_revision} 4 | Revises: ${down_revision | comma,n} 5 | Create Date: ${create_date} 6 | 7 | """ 8 | from alembic import op 9 | import sqlalchemy as sa 10 | ${imports if imports else ""} 11 | 12 | # revision identifiers, used by Alembic. 13 | revision = ${repr(up_revision)} 14 | down_revision = ${repr(down_revision)} 15 | branch_labels = ${repr(branch_labels)} 16 | depends_on = ${repr(depends_on)} 17 | 18 | 19 | def upgrade(): 20 | ${upgrades if upgrades else "pass"} 21 | 22 | 23 | def downgrade(): 24 | ${downgrades if downgrades else "pass"} 25 | -------------------------------------------------------------------------------- /examples/test_schema_revision_data/migrations/versions/aaaaaaaaaaaa_create_foo.py: -------------------------------------------------------------------------------- 1 | import sqlalchemy as sa 2 | from alembic import op 3 | from sqlalchemy import text 4 | 5 | revision = "aaaaaaaaaaaa" 6 | down_revision = None 7 | branch_labels = None 8 | depends_on = None 9 | 10 | 11 | def upgrade(): 12 | op.execute(text("CREATE SCHEMA meow")) 13 | 14 | op.create_table( 15 | "foo", 16 | sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), 17 | sa.PrimaryKeyConstraint("id"), 18 | schema="meow", 19 | ) 20 | 21 | 22 | def downgrade(): 23 | op.drop_table("foo", schema="meow") 24 | op.execute("DROP SCHEMA meow") 25 | -------------------------------------------------------------------------------- /examples/test_schema_revision_data/migrations/versions/bbbbbbbbbbbb_update_foo.py: -------------------------------------------------------------------------------- 1 | from alembic import op 2 | from sqlalchemy import text 3 | 4 | revision = "bbbbbbbbbbbb" 5 | down_revision = "aaaaaaaaaaaa" 6 | branch_labels = None 7 | depends_on = None 8 | 9 | 10 | def upgrade(): 11 | conn = op.get_bind() 12 | result = conn.execute(text("SELECT * FROM meow.foo")).fetchall() 13 | assert len(result) == 1 14 | assert result[0].id == 9, f"{result[0].id} == 9" 15 | 16 | 17 | def downgrade(): 18 | pass 19 | -------------------------------------------------------------------------------- /examples/test_schema_revision_data/models.py: -------------------------------------------------------------------------------- 1 | from sqlalchemy import Column, types 2 | 3 | try: 4 | from sqlalchemy.orm import declarative_base 5 | except ImportError: 6 | from sqlalchemy.ext.declarative import declarative_base 7 | 8 | 9 | Base = declarative_base() 10 | 11 | 12 | class Foo(Base): 13 | __tablename__ = "foo" 14 | __table_args__ = {"schema": "meow"} 15 | 16 | id = Column(types.Integer(), autoincrement=True, primary_key=True) 17 | -------------------------------------------------------------------------------- /examples/test_schema_revision_data/setup.cfg: -------------------------------------------------------------------------------- 1 | [tool:pytest] 2 | pytest_alembic_exclude = model_definitions_match_ddl 3 | -------------------------------------------------------------------------------- /examples/test_skip_revision/alembic.ini: -------------------------------------------------------------------------------- 1 | [alembic] 2 | script_location = migrations 3 | 4 | [loggers] 5 | keys = root,sqlalchemy,alembic 6 | 7 | [handlers] 8 | keys = console 9 | 10 | [formatters] 11 | keys = generic 12 | 13 | [logger_root] 14 | level = WARN 15 | handlers = console 16 | qualname = 17 | 18 | [logger_sqlalchemy] 19 | level = WARN 20 | handlers = 21 | qualname = sqlalchemy.engine 22 | 23 | [logger_alembic] 24 | level = INFO 25 | handlers = 26 | qualname = alembic 27 | 28 | [handler_console] 29 | class = StreamHandler 30 | args = (sys.stderr,) 31 | level = NOTSET 32 | formatter = generic 33 | 34 | [formatter_generic] 35 | format = %(levelname)-5.5s [%(name)s] %(message)s 36 | datefmt = %H:%M:%S 37 | -------------------------------------------------------------------------------- /examples/test_skip_revision/conftest.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | 3 | from pytest_alembic import Config 4 | 5 | 6 | @pytest.fixture() 7 | def alembic_config(): 8 | return Config(skip_revisions=["bbbbbbbbbbbb"]) 9 | -------------------------------------------------------------------------------- /examples/test_skip_revision/migrations/env.py: -------------------------------------------------------------------------------- 1 | from logging.config import fileConfig 2 | 3 | from alembic import context 4 | from models import Base 5 | from sqlalchemy import engine_from_config, pool 6 | 7 | fileConfig(context.config.config_file_name) 8 | target_metadata = Base.metadata 9 | 10 | 11 | connectable = context.config.attributes.get("connection", None) 12 | 13 | if connectable is None: 14 | connectable = engine_from_config( 15 | context.config.get_section(context.config.config_ini_section), 16 | prefix="sqlalchemy.", 17 | poolclass=pool.NullPool, 18 | ) 19 | 20 | with connectable.connect() as connection: 21 | context.configure(connection=connection, target_metadata=target_metadata) 22 | 23 | with context.begin_transaction(): 24 | context.run_migrations() 25 | -------------------------------------------------------------------------------- /examples/test_skip_revision/migrations/script.py.mako: -------------------------------------------------------------------------------- 1 | """${message} 2 | 3 | Revision ID: ${up_revision} 4 | Revises: ${down_revision | comma,n} 5 | Create Date: ${create_date} 6 | 7 | """ 8 | from alembic import op 9 | import sqlalchemy as sa 10 | ${imports if imports else ""} 11 | 12 | # revision identifiers, used by Alembic. 13 | revision = ${repr(up_revision)} 14 | down_revision = ${repr(down_revision)} 15 | branch_labels = ${repr(branch_labels)} 16 | depends_on = ${repr(depends_on)} 17 | 18 | 19 | def upgrade(): 20 | ${upgrades if upgrades else "pass"} 21 | 22 | 23 | def downgrade(): 24 | ${downgrades if downgrades else "pass"} 25 | -------------------------------------------------------------------------------- /examples/test_skip_revision/migrations/versions/aaaaaaaaaaaa_create_foo.py: -------------------------------------------------------------------------------- 1 | import sqlalchemy as sa 2 | from alembic import op 3 | 4 | revision = "aaaaaaaaaaaa" 5 | down_revision = None 6 | branch_labels = None 7 | depends_on = None 8 | 9 | 10 | def upgrade(): 11 | op.create_table( 12 | "foo", 13 | sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), 14 | sa.Column( 15 | "created_at", 16 | sa.DateTime(timezone=True), 17 | server_default=sa.text("(CURRENT_TIMESTAMP)"), 18 | nullable=False, 19 | ), 20 | sa.PrimaryKeyConstraint("id"), 21 | ) 22 | 23 | 24 | def downgrade(): 25 | op.drop_table("foo") 26 | -------------------------------------------------------------------------------- /examples/test_skip_revision/migrations/versions/bbbbbbbbbbb_raise.py: -------------------------------------------------------------------------------- 1 | revision = "bbbbbbbbbbbb" 2 | down_revision = "aaaaaaaaaaaa" 3 | branch_labels = None 4 | depends_on = None 5 | 6 | 7 | def upgrade(): 8 | raise 9 | 10 | 11 | def downgrade(): 12 | raise 13 | -------------------------------------------------------------------------------- /examples/test_skip_revision/migrations/versions/cccccccccccc_success.py: -------------------------------------------------------------------------------- 1 | revision = "cccccccccccc" 2 | down_revision = "bbbbbbbbbbbb" 3 | branch_labels = None 4 | depends_on = None 5 | 6 | 7 | def upgrade(): 8 | pass 9 | 10 | 11 | def downgrade(): 12 | pass 13 | -------------------------------------------------------------------------------- /examples/test_skip_revision/models.py: -------------------------------------------------------------------------------- 1 | import sqlalchemy 2 | from sqlalchemy import Column, types 3 | 4 | try: 5 | from sqlalchemy.orm import declarative_base 6 | except ImportError: 7 | from sqlalchemy.ext.declarative import declarative_base 8 | 9 | 10 | Base = declarative_base() 11 | 12 | 13 | class CreatedAt(Base): 14 | __tablename__ = "foo" 15 | 16 | id = Column(types.Integer(), autoincrement=True, primary_key=True) 17 | 18 | created_at = sqlalchemy.Column( 19 | sqlalchemy.types.DateTime(timezone=True), 20 | server_default=sqlalchemy.text("CURRENT_TIMESTAMP"), 21 | nullable=False, 22 | ) 23 | -------------------------------------------------------------------------------- /examples/test_unimplemented_downgrade_warning/alembic.ini: -------------------------------------------------------------------------------- 1 | [alembic] 2 | script_location = migrations 3 | 4 | [loggers] 5 | keys = root,sqlalchemy,alembic 6 | 7 | [handlers] 8 | keys = console 9 | 10 | [formatters] 11 | keys = generic 12 | 13 | [logger_root] 14 | level = WARN 15 | handlers = console 16 | qualname = 17 | 18 | [logger_sqlalchemy] 19 | level = WARN 20 | handlers = 21 | qualname = sqlalchemy.engine 22 | 23 | [logger_alembic] 24 | level = INFO 25 | handlers = 26 | qualname = alembic 27 | 28 | [handler_console] 29 | class = StreamHandler 30 | args = (sys.stderr,) 31 | level = NOTSET 32 | formatter = generic 33 | 34 | [formatter_generic] 35 | format = %(levelname)-5.5s [%(name)s] %(message)s 36 | datefmt = %H:%M:%S 37 | -------------------------------------------------------------------------------- /examples/test_unimplemented_downgrade_warning/conftest.py: -------------------------------------------------------------------------------- 1 | from pytest_mock_resources import create_postgres_fixture 2 | 3 | alembic_engine = create_postgres_fixture() 4 | -------------------------------------------------------------------------------- /examples/test_unimplemented_downgrade_warning/migrations/env.py: -------------------------------------------------------------------------------- 1 | from logging.config import fileConfig 2 | 3 | from alembic import context 4 | from models import Base 5 | from sqlalchemy import engine_from_config, pool 6 | 7 | fileConfig(context.config.config_file_name) 8 | target_metadata = Base.metadata 9 | 10 | 11 | connectable = context.config.attributes.get("connection", None) 12 | 13 | if connectable is None: 14 | connectable = engine_from_config( 15 | context.config.get_section(context.config.config_ini_section), 16 | prefix="sqlalchemy.", 17 | poolclass=pool.NullPool, 18 | ) 19 | 20 | 21 | with connectable.connect() as connection: 22 | context.configure(connection=connection, target_metadata=target_metadata) 23 | 24 | with context.begin_transaction(): 25 | context.run_migrations() 26 | -------------------------------------------------------------------------------- /examples/test_unimplemented_downgrade_warning/migrations/script.py.mako: -------------------------------------------------------------------------------- 1 | """${message} 2 | 3 | Revision ID: ${up_revision} 4 | Revises: ${down_revision | comma,n} 5 | Create Date: ${create_date} 6 | 7 | """ 8 | from alembic import op 9 | import sqlalchemy as sa 10 | ${imports if imports else ""} 11 | 12 | # revision identifiers, used by Alembic. 13 | revision = ${repr(up_revision)} 14 | down_revision = ${repr(down_revision)} 15 | branch_labels = ${repr(branch_labels)} 16 | depends_on = ${repr(depends_on)} 17 | 18 | 19 | def upgrade(): 20 | ${upgrades if upgrades else "pass"} 21 | 22 | 23 | def downgrade(): 24 | ${downgrades if downgrades else "pass"} 25 | -------------------------------------------------------------------------------- /examples/test_unimplemented_downgrade_warning/migrations/versions/aaaaaaaaaaaa_create_foo.py: -------------------------------------------------------------------------------- 1 | import sqlalchemy as sa 2 | from alembic import op 3 | 4 | revision = "aaaaaaaaaaaa" 5 | down_revision = None 6 | branch_labels = None 7 | depends_on = None 8 | 9 | 10 | def upgrade(): 11 | op.create_table( 12 | "foo", 13 | sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), 14 | sa.PrimaryKeyConstraint("id"), 15 | ) 16 | 17 | 18 | def downgrade(): 19 | op.drop_table("foo") 20 | -------------------------------------------------------------------------------- /examples/test_unimplemented_downgrade_warning/migrations/versions/bbbbbbbbbbbb_create_foo.py: -------------------------------------------------------------------------------- 1 | from alembic import op 2 | 3 | revision = "bbbbbbbbbbbb" 4 | down_revision = "aaaaaaaaaaaa" 5 | branch_labels = None 6 | depends_on = None 7 | 8 | 9 | def upgrade(): 10 | op.get_bind() 11 | op.execute("DELETE FROM foo") 12 | 13 | 14 | def downgrade(): 15 | raise NotImplementedError 16 | -------------------------------------------------------------------------------- /examples/test_unimplemented_downgrade_warning/migrations/versions/cccccccccccc_create_foo.py: -------------------------------------------------------------------------------- 1 | import sqlalchemy as sa 2 | from alembic import op 3 | 4 | revision = "cccccccccccc" 5 | down_revision = "bbbbbbbbbbbb" 6 | branch_labels = None 7 | depends_on = None 8 | 9 | 10 | def upgrade(): 11 | op.add_column("foo", sa.Column("foo_id", sa.Integer(), server_default="9")) 12 | 13 | 14 | def downgrade(): 15 | op.drop_column("foo", "foo_id") 16 | -------------------------------------------------------------------------------- /examples/test_unimplemented_downgrade_warning/models.py: -------------------------------------------------------------------------------- 1 | from sqlalchemy import Column, types 2 | 3 | try: 4 | from sqlalchemy.orm import declarative_base 5 | except ImportError: 6 | from sqlalchemy.ext.declarative import declarative_base 7 | 8 | 9 | Base = declarative_base() 10 | 11 | 12 | class CreatedAt(Base): 13 | __tablename__ = "foo" 14 | 15 | id = Column(types.Integer(), autoincrement=True, primary_key=True) 16 | foo_id = Column(types.Integer()) 17 | -------------------------------------------------------------------------------- /examples/test_unimplemented_downgrade_warning/setup.cfg: -------------------------------------------------------------------------------- 1 | [tool:pytest] 2 | pytest_alembic_include_experimental = downgrade_leaves_no_trace 3 | filterwarnings = ignore::DeprecationWarning 4 | -------------------------------------------------------------------------------- /examples/test_version_table_schema/alembic.ini: -------------------------------------------------------------------------------- 1 | [alembic] 2 | script_location = migrations 3 | 4 | [loggers] 5 | keys = root,sqlalchemy,alembic 6 | 7 | [handlers] 8 | keys = console 9 | 10 | [formatters] 11 | keys = generic 12 | 13 | [logger_root] 14 | level = WARN 15 | handlers = console 16 | qualname = 17 | 18 | [logger_sqlalchemy] 19 | level = WARN 20 | handlers = 21 | qualname = sqlalchemy.engine 22 | 23 | [logger_alembic] 24 | level = INFO 25 | handlers = 26 | qualname = alembic 27 | 28 | [handler_console] 29 | class = StreamHandler 30 | args = (sys.stderr,) 31 | level = NOTSET 32 | formatter = generic 33 | 34 | [formatter_generic] 35 | format = %(levelname)-5.5s [%(name)s] %(message)s 36 | datefmt = %H:%M:%S 37 | -------------------------------------------------------------------------------- /examples/test_version_table_schema/conftest.py: -------------------------------------------------------------------------------- 1 | from pytest_mock_resources import create_postgres_fixture, Statements 2 | 3 | alembic_engine = create_postgres_fixture(Statements("CREATE SCHEMA version_table_schema")) 4 | -------------------------------------------------------------------------------- /examples/test_version_table_schema/migrations/env.py: -------------------------------------------------------------------------------- 1 | from logging.config import fileConfig 2 | 3 | from alembic import context 4 | from models import Base 5 | from sqlalchemy import engine_from_config, pool 6 | 7 | fileConfig(context.config.config_file_name) 8 | target_metadata = Base.metadata 9 | 10 | 11 | connectable = context.config.attributes.get("connection", None) 12 | 13 | if connectable is None: 14 | connectable = engine_from_config( 15 | context.config.get_section(context.config.config_ini_section), 16 | prefix="sqlalchemy.", 17 | poolclass=pool.NullPool, 18 | ) 19 | 20 | with connectable.connect() as connection: 21 | context.configure( 22 | connection=connection, 23 | target_metadata=target_metadata, 24 | version_table_schema="version_table_schema", 25 | ) 26 | 27 | with context.begin_transaction(): 28 | context.run_migrations() 29 | -------------------------------------------------------------------------------- /examples/test_version_table_schema/migrations/script.py.mako: -------------------------------------------------------------------------------- 1 | """${message} 2 | 3 | Revision ID: ${up_revision} 4 | Revises: ${down_revision | comma,n} 5 | Create Date: ${create_date} 6 | 7 | """ 8 | from alembic import op 9 | import sqlalchemy as sa 10 | ${imports if imports else ""} 11 | 12 | # revision identifiers, used by Alembic. 13 | revision = ${repr(up_revision)} 14 | down_revision = ${repr(down_revision)} 15 | branch_labels = ${repr(branch_labels)} 16 | depends_on = ${repr(depends_on)} 17 | 18 | 19 | def upgrade(): 20 | ${upgrades if upgrades else "pass"} 21 | 22 | 23 | def downgrade(): 24 | ${downgrades if downgrades else "pass"} 25 | -------------------------------------------------------------------------------- /examples/test_version_table_schema/migrations/versions/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schireson/pytest-alembic/47748802f22db988fb95926189eb78ec59ad387f/examples/test_version_table_schema/migrations/versions/.gitkeep -------------------------------------------------------------------------------- /examples/test_version_table_schema/migrations/versions/aaaaaaaaaaaa_create_foo.py: -------------------------------------------------------------------------------- 1 | import sqlalchemy as sa 2 | from alembic import op 3 | 4 | revision = "aaaaaaaaaaaa" 5 | down_revision = None 6 | branch_labels = None 7 | depends_on = None 8 | 9 | 10 | def upgrade(): 11 | op.create_table( 12 | "foo", 13 | sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), 14 | sa.Column( 15 | "created_at", 16 | sa.DateTime(timezone=True), 17 | server_default=sa.text("(CURRENT_TIMESTAMP)"), 18 | nullable=False, 19 | ), 20 | sa.PrimaryKeyConstraint("id"), 21 | ) 22 | 23 | 24 | def downgrade(): 25 | op.drop_table("foo") 26 | -------------------------------------------------------------------------------- /examples/test_version_table_schema/models.py: -------------------------------------------------------------------------------- 1 | import sqlalchemy 2 | from sqlalchemy import Column, types 3 | 4 | try: 5 | from sqlalchemy.orm import declarative_base 6 | except ImportError: 7 | from sqlalchemy.ext.declarative import declarative_base 8 | 9 | 10 | Base = declarative_base() 11 | 12 | 13 | class CreatedAt(Base): 14 | __tablename__ = "foo" 15 | 16 | id = Column(types.Integer(), autoincrement=True, primary_key=True) 17 | 18 | created_at = sqlalchemy.Column( 19 | sqlalchemy.types.DateTime(timezone=True), 20 | server_default=sqlalchemy.text("CURRENT_TIMESTAMP"), 21 | nullable=False, 22 | ) 23 | -------------------------------------------------------------------------------- /examples/test_version_table_schema/setup.cfg: -------------------------------------------------------------------------------- 1 | [tool:pytest] 2 | pytest_alembic_exclude = single_head_revision 3 | pytest_alembic_include_experimental = downgrade_leaves_no_trace,all_models_register_on_metadata 4 | -------------------------------------------------------------------------------- /readthedocs.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | 3 | sphinx: 4 | configuration: docs/source/conf.py 5 | 6 | build: 7 | os: "ubuntu-22.04" 8 | tools: 9 | python: "3.10" 10 | 11 | formats: all 12 | 13 | python: 14 | install: 15 | - requirements: docs/requirements.txt 16 | -------------------------------------------------------------------------------- /src/pytest_alembic/__init__.py: -------------------------------------------------------------------------------- 1 | from pytest_alembic.config import Config 2 | from pytest_alembic.plugin.fixtures import create_alembic_fixture 3 | from pytest_alembic.runner import MigrationContext, runner 4 | 5 | __all__ = [ 6 | "Config", 7 | "create_alembic_fixture", 8 | "MigrationContext", 9 | "runner", 10 | ] 11 | -------------------------------------------------------------------------------- /src/pytest_alembic/plugin/__init__.py: -------------------------------------------------------------------------------- 1 | # flake8: noqa 2 | from pytest_alembic.plugin.fixtures import alembic_config, alembic_engine, alembic_runner 3 | from pytest_alembic.plugin.hooks import pytest_addoption, pytest_configure, pytest_sessionstart 4 | -------------------------------------------------------------------------------- /src/pytest_alembic/plugin/error.py: -------------------------------------------------------------------------------- 1 | import textwrap 2 | from typing import List 3 | 4 | 5 | class AlembicTestFailure(AssertionError): # noqa: N818 6 | def __init__(self, message, context=None): 7 | super().__init__(message) 8 | self.context = context 9 | self.exce = self 10 | self.item = None 11 | 12 | def format_context(self) -> List[str]: 13 | """Print out a custom error message to the terminal.""" 14 | result = [] 15 | if not self.context: 16 | return [] 17 | 18 | for title, item in self.context: 19 | result.extend(["", f"{title}:", textwrap.indent(item, " ")]) 20 | return result 21 | 22 | def __str__(self): 23 | content = self.format_context() 24 | segments = [super().__str__(), *content] 25 | return "\n".join(segments) 26 | -------------------------------------------------------------------------------- /src/pytest_alembic/py.typed: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schireson/pytest-alembic/47748802f22db988fb95926189eb78ec59ad387f/src/pytest_alembic/py.typed -------------------------------------------------------------------------------- /src/pytest_alembic/tests/__init__.py: -------------------------------------------------------------------------------- 1 | from pytest_alembic.tests.default import ( 2 | test_model_definitions_match_ddl, 3 | test_single_head_revision, 4 | test_up_down_consistency, 5 | test_upgrade, 6 | ) 7 | 8 | __all__ = [ 9 | "test_model_definitions_match_ddl", 10 | "test_single_head_revision", 11 | "test_up_down_consistency", 12 | "test_upgrade", 13 | ] 14 | -------------------------------------------------------------------------------- /src/pytest_alembic/tests/experimental/__init__.py: -------------------------------------------------------------------------------- 1 | from pytest_alembic.tests.experimental.all_models_register_on_metadata import ( 2 | test_all_models_register_on_metadata, 3 | ) 4 | from pytest_alembic.tests.experimental.downgrade_leaves_no_trace import ( 5 | test_downgrade_leaves_no_trace, 6 | ) 7 | 8 | __all__ = [ 9 | "test_all_models_register_on_metadata", 10 | "test_downgrade_leaves_no_trace", 11 | ] 12 | -------------------------------------------------------------------------------- /tests/__init__.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | import sqlalchemy 3 | 4 | sqlalchemy_version = getattr(sqlalchemy, "version", "1.3") 5 | supports_asyncio = sqlalchemy_version.startswith(("1.4", "2.")) 6 | 7 | requires_asyncio_support = pytest.mark.skipif( 8 | not supports_asyncio, 9 | reason="Requires asyncio support", 10 | ) 11 | -------------------------------------------------------------------------------- /tests/conftest.py: -------------------------------------------------------------------------------- 1 | from pytest_mock_resources import create_postgres_fixture 2 | 3 | pytest_plugins = "pytester" 4 | 5 | db = create_postgres_fixture() 6 | -------------------------------------------------------------------------------- /tests/plugin/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schireson/pytest-alembic/47748802f22db988fb95926189eb78ec59ad387f/tests/plugin/__init__.py -------------------------------------------------------------------------------- /tests/test_executor.py: -------------------------------------------------------------------------------- 1 | from pytest_mock_resources import create_postgres_fixture 2 | from sqlalchemy import Column, MetaData, Table, types 3 | 4 | from pytest_alembic.executor import ConnectionExecutor 5 | 6 | metadata = MetaData() 7 | 8 | table = Table("t", metadata, Column("name", types.Unicode(), primary_key=True)) 9 | 10 | pg = create_postgres_fixture(metadata) 11 | 12 | 13 | def test_table_insert(pg): 14 | command_executor = ConnectionExecutor(pg) 15 | command_executor.table_insert("", [{"name": "who"}], tablename="t") 16 | -------------------------------------------------------------------------------- /tests/tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schireson/pytest-alembic/47748802f22db988fb95926189eb78ec59ad387f/tests/tests/__init__.py -------------------------------------------------------------------------------- /tests/tests/experimental/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schireson/pytest-alembic/47748802f22db988fb95926189eb78ec59ad387f/tests/tests/experimental/__init__.py --------------------------------------------------------------------------------