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.16pytest>= 8.4
pytest-xdist>= 3.0 (Optional)pytest-asyncio>= 1.3.0 (Optional)
Supported dialects
| Driver | Status |
|---|---|
sqlite+pysqlite |
✅ Supported |
sqlite+pysqlcipher |
✅ Supported |
postgresql+psycopg |
✅ Supported |
postgresql+psycopg2 |
✅ Supported |
postgresql+pg8000 |
✅ Supported |
postgresql+psycopg2cffi |
✅ Supported |
postgresql+asyncpg |
✅ Supported |
mariadb+mysqldb |
✅ Supported |
mariadb+pymysql |
✅ Supported |
mariadb+mariadbconnector |
✅ Supported |
mariadb+asyncmy |
✅ Supported |
mariadb+aiomysql |
✅ Supported |
mariadb+cymysql |
✅ Supported |
mysql+mysqldb |
✅ Supported |
mysql+pymysql |
✅ Supported |
mysql+mysqlconnector |
✅ Supported |
mysql+asyncmy |
✅ Supported |
mysql+aiomysql |
✅ Supported |
mysql+cymysql |
✅ Supported |
[!NOTE] If you need an implementation for your particular SQLAlchemy driver, please consider contributing to this project.
Installation
pip install pytest-sqlalchemy-alembic
or
pip install pytest-sqlalchemy-alembic[xdist] # with pytest-xdist
pip install pytest-sqlalchemy-alembic[async] # with pytest-asyncio
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_alembic_configs = [
{session_maker = "example_project_async.db:AsyncSessionLocal"},
]
In TOML, array of tables should be used to provide config values
pytest.ini
[pytest]
sqlalchemy_alembic_configs =
{"session_maker": "example_project.db:SessionLocal"}
In INI each line should be a valid JSON object
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_configs(pytestconfig: pytest.Config) -> list[PluginConfig]:
return [
PluginConfig.build(
session_maker=SessionLocal,
create_db=pytestconfig.getoption('create_db'),
no_migrations=pytestconfig.getoption('no_migrations'),
)
]
Full list of configuration options
Config file options
| Option | Description |
|---|---|
session_maker |
Import path to a sessionmaker instance |
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 |
engine |
Import path to SQLAlchemy engine instance. If empty, created using engine_url and engine_kwargs or extracted from the sessionmaker instance |
engine_url |
SQLAlchemy engine URL. Extracted from engine if empty |
engine_kwargs |
Import path to a dict containing engine kwargs |
orm_loader |
Import path to module or callable that loads all ORM necessary models |
scope |
Defines at which scope test engine should be activated (session or function). Default: session |
skip_db_management |
If this entry should skip test database management. Useful in case of multiple engines, which use the same database. Default: false |
Fixture override options
Arguments of PluginConfig.build class method to use in the sqlalchemy_alembic_plugin_configs fixture.
| Argument | Type | Description |
|---|---|---|
session_maker |
sa.orm.sessionmaker[Session] |
Instance of a sessionmaker |
metadata |
sa.MetaData | Sequence[sa.MetaData] |
SQLAlchemy 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 |
scope |
Literal['session', 'function'] |
Defines at which scope test engine should be activated |
skip_db_management |
bool |
If this entry should skip test database management. Useful in case of multiple engines, which use the same database |
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_plugin_configs |
session | List of this plugin configs | Extension point to override config values from python context |
sqlalchemy_alembic_setup_session |
session | Sequence of test SQLAlchemy engines | Session-scoped fixture to set up test database and engine |
sqlalchemy_alembic_setup_function |
function | Sequence of test SQLAlchemy engines or None's |
Function-scoped fixture to set up test engine. Used only in case of scope='function' |
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.2.0.tar.gz.
File metadata
- Download URL: pytest_sqlalchemy_alembic-0.2.0.tar.gz
- Upload date:
- Size: 11.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.11.24 {"installer":{"name":"uv","version":"0.11.24","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 |
7eea80a9a3ee2a37077f27fca604c501d871e61fc40bc4f793c13550cc33a554
|
|
| MD5 |
46bcabd81f3f5b5ded2cc9f9403ffb3a
|
|
| BLAKE2b-256 |
4b4146d5b90dbf317ad684b40f12ecd2470f06fb14aec408b960601b091358c8
|
File details
Details for the file pytest_sqlalchemy_alembic-0.2.0-py3-none-any.whl.
File metadata
- Download URL: pytest_sqlalchemy_alembic-0.2.0-py3-none-any.whl
- Upload date:
- Size: 16.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.11.24 {"installer":{"name":"uv","version":"0.11.24","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 |
b53eba7d4aa2465678d822d25d474b4af12f9fcd0cb68fd77c11e70133559e66
|
|
| MD5 |
f940343bd4439d9ea64242c70fc61dca
|
|
| BLAKE2b-256 |
ce132cb6e689a8f79f60e8690628a47f9e06591a87d4fde2d8d6f7585e92d748
|