Skip to main content

django-baseshift-brancher

Run your Django test suite against an already-migrated PostgreSQL clone, so tests don't need to run CREATE DATABASE or migrations on every run.

On a large Django project, a lot of test time goes to building the test database and replaying every migration. django-baseshift-brancher skips both steps. It uses brancher by Baseshift to create one ready-to-use PostgreSQL clone per test worker, already migrated to the schema of your current git checkout. Then it points pytest or Django's test runner at those clones.

  • Works with pytest / pytest-django (pytest -n N) and Django's manage.py test (--parallel N)
  • No changes to settings.py
  • Migrated snapshots are cached per migration commit and shared across branches

Requirements

Requirement Version
Python 3.8 – 3.13
Django 3.2, 4.2, 5.0 – 6.0
Database PostgreSQL
brancher by Baseshift The baseshift binary must be on your PATH (install brancher)
Git Your project must be a git repository

Install

pip install django-baseshift-brancher

# If pytest-django isn't installed yet:
pip install "django-baseshift-brancher[pytest]"

Quick start

Run these from your Django project root (the directory that contains manage.py).

1. Create the clones

export DJANGO_SETTINGS_MODULE=yourproject.settings
unset BASESHIFT_BRANCHES_FILE DATABASE_URL PGHOST PGPORT

django-baseshift-brancher clone --count 4

--count is the number of databases to create. You need one per test worker.

The command writes the clone details to .brancher/clones.json, prints them as JSON, and prints the export line you need next (on stderr).

2. Run the tests

pytest

export BASESHIFT_BRANCHES_FILE="$PWD/.brancher/clones.json"
pytest -n 4

Django test runner

export BASESHIFT_BRANCHES_FILE="$PWD/.brancher/clones.json"
python manage.py test --testrunner django_baseshift_brancher.DiscoverRunner --parallel 4

3. Clean up

baseshift stop --all

How it works

Snapshots follow your migration history

clone reads your git history. Every commit that changes migration files gets its own migrated snapshot.

  • Adding migration files builds on the previous snapshot. Branches that split off from the same migration commit share it.
  • Changing or deleting existing migration files starts over from an empty snapshot, because the new schema can't be built on top of the old one.
  • Rebasing creates new commits, so the rebased checkout gets a new snapshot on top of its new parent. Branches that split off before the rebase keep their own chain.

Snapshots don't have names and you never manage them yourself. Parent snapshots are picked automatically.

Test workers map to clones

Runner Worker ID Clone used
pytest-xdist gw0, gw1, … (0-based) gw0 → 1st clone
Django --parallel "1", "2", … (1-based) "1" → 1st clone

pytest -n 4 and --parallel 4 each need --count 4 (or more).

What happens to your DATABASES setting

  • USER and PASSWORD are kept as you configured them.
  • HOST, PORT and NAME are replaced with the clone's values.
  • Test migrations are turned off (the clone is already migrated).

pytest plugin

The plugin loads automatically. It assigns each worker to a clone and forces --reuse-db and --no-migrations. Don't pass --create-db.


Configuration

Environment variable Required Purpose
DJANGO_SETTINGS_MODULE Yes Your Django settings module
BASESHIFT_BRANCHES_FILE Yes, when running tests Absolute path to .brancher/clones.json. Tests only read the clones from this variable. A clones.json in the current directory is not picked up automatically.
BASESHIFT_INIT_SQL No SQL that runs on each new snapshot before migrate. Use it for anything your migrations assume already exists, such as extensions.

Example:

export BASESHIFT_INIT_SQL="CREATE EXTENSION IF NOT EXISTS pg_trgm"

Other setup commands: once the clones are running, run any extra project setup yourself against their connection strings (for example, a management command like ensure_celery_broker_schema).


Troubleshooting

Symptom Likely cause Fix
Tests connect to your normal dev/CI database BASESHIFT_BRANCHES_FILE isn't set in the shell running the tests export BASESHIFT_BRANCHES_FILE="$PWD/.brancher/clones.json"
Some workers fail or no clone is found for them Fewer clones than workers Re-run clone with --count ≥ -n / --parallel
Tests try to create the database --create-db was passed Remove --create-db
A migration fails with a missing extension The extension has to exist before migrations run Set BASESHIFT_INIT_SQL and re-run clone
baseshift: command not found brancher isn't installed Install it from baseshift.com/brancher

For AI coding agents

Use this exact sequence from the Django project root. Replace N with the number of parallel test workers.

export DJANGO_SETTINGS_MODULE=<project>.settings
unset BASESHIFT_BRANCHES_FILE DATABASE_URL PGHOST PGPORT
django-baseshift-brancher clone --count N
export BASESHIFT_BRANCHES_FILE="$PWD/.brancher/clones.json"
pytest -n N                     # or: python manage.py test --testrunner django_baseshift_brancher.DiscoverRunner --parallel N
baseshift stop --all

Rules:

  • Don't edit settings.py.
  • Don't pass --create-db.
  • Re-run clone after checking out a commit with different migrations.
  • BASESHIFT_BRANCHES_FILE must be exported in the same shell that runs the tests.
  • Always run baseshift stop --all when you're done.

About Baseshift

Baseshift gives every developer, coding agent and pull request its own isolated, writable, masked clone of your real database, running in your cloud and ready in seconds. It supports PostgreSQL, MySQL, MongoDB and MariaDB. It also adds guardrails for database changes, such as schema change detection and query risk checks, so issues are caught before they reach production.

This package is the Django integration for brancher by Baseshift.

License

Proprietary. See baseshift.com for terms.

Metadata

Release files for django-baseshift-brancher 0.13.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for django-baseshift-brancher 0.13.0
File Size Uploaded
django_baseshift_brancher-0.13.0.tar.gz 53.3 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for django-baseshift-brancher 0.13.0
File Interpreter ABI Platform
django_baseshift_brancher-0.13.0-py3-none-any.whl Python 3 none any Details

Total release size: 94.3 kB

Release files / django_baseshift_brancher-0.13.0.tar.gz

Download URL django_baseshift_brancher-0.13.0.tar.gz
Size 53.3 kB
Tags Source
SHA-256 checksum
How to use checksums
ff8dec5673943fdf4392923ab1bfba24120ac9c95a4fbbf0fbb2a9a99131dc56
BLAKE2b-256 checksum
How to use checksums
18827176c93fb7e889eccd8a9e51005f7768b866de852b06f2592b9918ac140c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.3

Release files / django_baseshift_brancher-0.13.0-py3-none-any.whl

Download URL django_baseshift_brancher-0.13.0-py3-none-any.whl
Size 41.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
c91865c1e86251558bf7b407f188dab15bcb8ce1ce14214911a5c587618ca4c7
BLAKE2b-256 checksum
How to use checksums
e88e815df3318e903e68b43c5b8f0cd2f92cdde906348017c6dbc7d60d203cd3
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.3

Release history Release notifications | RSS feed

1.5.0

2 release files

1.4.0

2 release files

1.3.2

2 release files

This release

0.13.0 This release

2 release files

0.12.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page