Pytest plugin to manage databases, sessions and migrations for sqlalchemy-based projects
Project description
pytest-sqlalchemy-alembic
A pytest plugin to manage test databases for SQLAlchemy-based projects.
It automatically provisions a dedicated test database per worker and runs Alembic migrations before your test session. Inspired by pytest-django.
How it works
- The plugin creates an SQLAlchemy test engine for each worker process.
- Test database is created or reused for each test engine. If
--createdbis given, the test database is dropped beforehand. - Database schema is populated via Alembic or directly from SQLAlchemy metadata (if
--nomigrationsis given). - If configured, the sessionmaker instance is rebound to the test engine for the duration of the test session.
Requirements
sqlalchemy>= 2.0alembic>= 1.17pytest>= 8.4pytest-xdist>= 3.0 (Optional)
Supported dialects
[!WARNING] Async engines are not yet supported
| Driver | Status |
|---|---|
postgresql+psycopg |
✅ Supported |
postgresql+psycopg2 |
✅ Supported |
postgresql+pg8000 |
❌ |
postgresql+psycopg2cffi |
❌ |
postgresql+asyncpg |
❌ |
mysql+pymysql |
❌ |
mariadb+pymysql |
❌ |
sqlite |
✅ Supported |
[!NOTE] If you need an implementation for your particular SQLAlchemy driver, please consider contributing to this project.
Installation
pip install pytest-sqlalchemy-alembic
Minimal configuration
Configuration could be done in pyproject.toml, pytest.ini or via pytest fixture. At least session_maker, engine or engine_url should be specified.
pyproject.toml
[tool.pytest.ini_options]
sqlalchemy_session_maker = "example_project.db:SessionLocal"
pytest.ini
[pytest]
sqlalchemy_session_maker = example_project.db:SessionLocal
conftest.py
import pytest
from pytest_sqlalchemy_alembic.config import PluginConfig
from example_project.db import SessionLocal
@pytest.fixture(scope='session')
def sqlalchemy_alembic_plugin_config() -> PluginConfig:
return PluginConfig.build(session_maker=SessionLocal)
Full list of configuration options
Config file options
| Option | Description |
|---|---|
sqlalchemy_session_maker |
Import path to a sessionmaker instance |
sqlalchemy_metadata |
Import path to SQLAlchemy metadata. Usually metadata attribute of a declarative base class. Used for non-alembic database schema population based on metadata. Metadata is extracted from the alembic config if this option is empty |
sqlalchemy_engine |
Import path to SQLAlchemy engine instance. If empty, created using engine_url and engine_kwargs or extracted from the sessionmaker instance |
sqlalchemy_engine_url |
SQLAlchemy engine URL. Extracted from engine if empty |
sqlalchemy_engine_kwargs |
Import path to a dict containing engine kwargs |
sqlalchemy_orm_loader |
Import path to module or callable that loads all ORM necessary models |
Fixture override options
Arguments of PluginConfig.build class method to use in the sqlalchemy_alembic_plugin_config fixture.
| Argument | Type | Description |
|---|---|---|
session_maker |
sa.orm.sessionmaker[Session] |
Instance of a sessionmaker |
metadata |
`sa.MetaData | Sequence[sa.MetaData]` |
engine |
sa.Engine |
Sqlalchemy engine instance |
engine_url |
str |
SQLAlchemy engine URL |
engine_kwargs |
dict[str, Any] |
dict with kwargs for sa.create_engine function. E.g. {'json_serializer': my_json_serializer} |
orm_loader |
Callable[[], Any] |
Callable, that will load all ORM necessary models |
Combining file configuration and fixture override
In this example session_maker will be defined in pyproject.toml and metadata will be directly imported in the conftest.py.
# pyproject.toml
[tool.pytest.ini_options]
sqlalchemy_session_maker = "example_project.db:SessionLocal"
# conftest.py
import pytest
from pytest_sqlalchemy_alembic.config import PluginConfig
from example_project.models import Base
@pytest.fixture(scope='session')
def sqlalchemy_alembic_plugin_config(pytestconfig: pytest.Config) -> PluginConfig:
return PluginConfig.build(config=pytestconfig, metadata=Base.metadata)
Usage
When configured, the plugin binds your sessionmaker to the test database automatically.
# services.py
from example_project.db import SessionLocal
def my_service():
with SessionLocal() as db:
return db.scalar(...)
# test_services.py
from example_project.services import my_service
def test_my_service():
my_service() # <-- test database will be used
[!NOTE] Usually you don't need to change any of your code to use test database instead of main one.
However, if you make database queries outside of your sessionmaker, you need to patch those places manually.
Pytest run flags
| Flag | Description |
|---|---|
--createdb / --create-db |
Drop and recreate the test database before the session |
--nomigrations / --no-migrations |
Skip Alembic migrations and use metadata.create_all() instead |
Fixtures
| Fixture | Scope | Output | Description |
|---|---|---|---|
sqlalchemy_alembic_setup |
session | Test SQLAlchemy engine | Autouse fixture that creates and migrates the test database and rebinds the configured sessionmaker |
sqlalchemy_alembic_plugin_config |
session | This plugin's config | Extension point to override config values from python context |
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pytest_sqlalchemy_alembic-0.1.0.tar.gz.
File metadata
- Download URL: pytest_sqlalchemy_alembic-0.1.0.tar.gz
- Upload date:
- Size: 7.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.11.19 {"installer":{"name":"uv","version":"0.11.19","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e5fee1f55306a403f94d3cf41931cd3a9a2f73e1541964172b6427187741c058
|
|
| MD5 |
eec95619ffc65f32331188c9f31da2ff
|
|
| BLAKE2b-256 |
ff192c9e3cdb3d9d9d95327748eb837d38b1d224702e7b4bc35ae54be5cec5b1
|
File details
Details for the file pytest_sqlalchemy_alembic-0.1.0-py3-none-any.whl.
File metadata
- Download URL: pytest_sqlalchemy_alembic-0.1.0-py3-none-any.whl
- Upload date:
- Size: 12.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.11.19 {"installer":{"name":"uv","version":"0.11.19","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a0730ec570a72849a314986552e789dd83d3ddb50097789af9a7d8fd6af3a77b
|
|
| MD5 |
c67f5f19ffcc0c5a0a1f3ec5c001b1b0
|
|
| BLAKE2b-256 |
f68a17e5440745d920aef7be4c8a742104cfeacdd0cd7cd01d103d7bed540497
|