Skip to content

Multiple databases

How to test apps that use more than one database.


Setup

Pass a binds dict to bluefox_test_setup():

conftest.py
from bluefox_test import bluefox_test_setup
from app.models import Base

globals().update(
    bluefox_test_setup(
        base=Base,
        binds={
            "analytics": "analytics.models:AnalyticsBase",
            "events": "events.models:EventsBase",
        },
    )
)

Each key in binds creates:

  • A test_<key> database inside the same Postgres container
  • A session-scoped engine that runs create_all() for that bind's base class
  • A function-scoped db_<key> fixture with its own SAVEPOINT session

Using bind sessions in tests

async def test_track_event(db, db_analytics, create_user, create_event):
    user = await create_user(name="Hugo")  # uses db (main)
    event = await create_event(user_id=user.id, action="login")  # uses db_analytics
    assert event.id is not None

Cross-bind factories

Register factories with the correct session fixture:

src/analytics/tests/factories.py
from bluefox_test import BaseFactory, Faker, register
from analytics.models import Event


class EventFactory(BaseFactory):
    class Meta:
        model = Event

    action = Faker("word")

create_event = register(EventFactory, session_fixture="db_analytics")

The session_fixture="db_analytics" parameter tells the fixture to inject the analytics session instead of the default db.


How it works internally

  1. start_containers() creates a single Postgres container
  2. create_bind_databases() creates additional databases (test_analytics, test_events) inside that container using psycopg2
  3. Each bind gets its own AsyncEngine and runs create_all() with its own base class
  4. Each db_<key> fixture wraps its engine in a SAVEPOINT session

All databases share the same Postgres container — no extra Docker overhead.