Metadata-Version: 2.4
Name: django-baseshift-brancher
Version: 0.6.0
Summary: Run Django and pytest against a Baseshift clone of an already-migrated PostgreSQL database.
Author: Baseshift
License-Expression: LicenseRef-Proprietary
Project-URL: Homepage, https://baseshift.io
Keywords: django,pytest,postgresql,baseshift
Classifier: Development Status :: 4 - Beta
Classifier: Framework :: Django
Classifier: Framework :: Django :: 3.2
Classifier: Framework :: Django :: 4.2
Classifier: Framework :: Django :: 5.0
Classifier: Framework :: Django :: 5.1
Classifier: Framework :: Django :: 5.2
Classifier: Framework :: Django :: 6.0
Classifier: Framework :: Pytest
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development :: Testing
Requires-Python: >=3.8
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: Django>=3.2
Provides-Extra: pytest
Requires-Dist: pytest>=6.2; extra == "pytest"
Requires-Dist: pytest-django>=4.5; extra == "pytest"
Provides-Extra: dev
Requires-Dist: pytest>=7; extra == "dev"
Requires-Dist: pytest-django>=4.5; extra == "dev"
Requires-Dist: psycopg[binary]>=3.1; extra == "dev"
Dynamic: license-file

# django-baseshift-brancher

Run Django and pytest against a PostgreSQL database that is already migrated, and optionally already seeded. Tests do not `CREATE DATABASE` and do not run migrations again.

This package does not include the `baseshift` program that creates those databases. Install that binary separately and put it on `PATH`. `init` creates an empty snapshot, `branch` runs migrations on a copy of it, and `clone` starts one Postgres per test worker. That program is not the PyPI project named `baseshift`. `django-baseshift-brancher init` forwards to the binary on `PATH`.

```bash
pip install django-baseshift-brancher
# if pytest-django is not already installed:
pip install 'django-baseshift-brancher[pytest]'
```

## Create a migrated branch

From the Django project directory:

```bash
export DJANGO_SETTINGS_MODULE=yourproject.settings
unset BASESHIFT_BRANCHES_FILE DATABASE_URL PGHOST PGPORT

django-baseshift-brancher init --encryption off
django-baseshift-brancher branch main --from main -- \
  django-baseshift-brancher setup path/to/seed.json
```

Omit `path/to/seed.json` when there is nothing to load. `setup` runs, in order: optional SQL (extensions), `migrate`, the fixture paths you passed, then optional management commands.

```bash
django-baseshift-brancher branch main --from main -- \
  django-baseshift-brancher setup path/to/seed.json \
    --sql "CREATE EXTENSION IF NOT EXISTS hstore" \
    --run ensure_celery_broker_schema
```

`--sql` and `--run` can be repeated. The same values can be passed as `BASESHIFT_INIT_SQL` and `BASESHIFT_SETUP_COMMANDS` (`;`-separated).

`setup` prints one JSON object. `applied` lists the migrations Django ran. `[]` means nothing new was applied. `baseshift branch` still saves a new snapshot whenever `setup` exits 0. To reuse a snapshot you already built for this schema, resolve it and skip `branch`:

```bash
django-baseshift-brancher resolve --label "$MIG_HASH"
```

Pass `--label "$MIG_HASH"` on `branch` when you want that lookup to work next time.

Unset `BASESHIFT_BRANCHES_FILE` before `branch`. If it is still set, `setup` connects to those clones instead of the writer database.

## Run tests

One clone per worker:

```bash
django-baseshift-brancher clone main --count 4 --json > clones.json
export BASESHIFT_BRANCHES_FILE="$PWD/clones.json"

pytest -n 4
django-baseshift-brancher stop --all
```

`clones.json` is not picked up from the working directory. The `BASESHIFT_BRANCHES_FILE` export is what the tests read.

pytest needs no `settings.py` change. The plugin loads itself, points each worker at one clone, and forces `--reuse-db` and `--no-migrations`. Do not pass `--create-db`.

Django's runner needs one flag:

```bash
python manage.py test --testrunner django_baseshift_brancher.DiscoverRunner --parallel 4
```

`--parallel 4` and `pytest -n 4` both need four clones. pytest worker `gw0` uses the first clone. Django's worker suffix is 1-based: `"1"` uses the first clone.

Existing `DATABASES` `USER` and `PASSWORD` are kept. `HOST`, `PORT`, and `NAME` are rewritten onto the clone, and migrations during tests are turned off.

## Seed once

Fixtures passed to `setup` are stored in the snapshot. Every clone already has those rows.

`BASESHIFT_FIXTURES` is different: those fixtures are loaded again on every test worker. Use it only for data that must be loaded per worker. Do not list the `setup` fixtures there.

```bash
export BASESHIFT_FIXTURES=myapp/fixtures/per_worker.json
```
