Development

This guide explains how to set up a local development environment for codegen_database, run tests, lint code, and build the documentation.

Prerequisites

You will need the following tools installed:

  • Python 3.10+

  • uv — dependency management and virtual environments

  • just — command runner

Install uv by following the uv installation instructions — prefer whatever method is listed as current there.

Install just by following the just installation instructions — prefer whatever method is listed as current there.

Fork and clone

Fork the repository on GitHub, then clone your fork:

git clone https://github.com/<your-username>/codegen_database
cd codegen_database

Install all dependency groups and activate the virtual environment:

uv sync --all-groups

Install the pre-commit hooks (runs ruff automatically on every commit). The hook is repo-wide, so run this from the workspace root:

just -f ../../justfile setup

Create the test database (separate from the playground database):

createdb codegen_database_test

Export the URL so tests and docs can find it:

export DATABASE_URL="postgresql+psycopg://localhost/codegen_database_test"

That’s it. You’re ready to develop.

Note

The playground (playground/) targets a different database — codegen_database by default — so that playground-generated schema does not interfere with the test suite. If you run the playground migrations, use a separate DATABASE_URL:

DATABASE_URL=postgresql+psycopg://localhost/codegen_database uv run alembic -c playground/alembic.ini upgrade head

Running tests

codegen_database uses pytest for testing.

Tests are organised into three directories that mirror the source tree under src/codegen_database/:

tests/unit/

Pure Python tests with no database dependency. These run instantly and cover things like factory configuration logic and template rendering. Fixtures that require a live database are intentionally unavailable here — pytest will error if a unit test accidentally references one.

tests/integration/

Tests that exercise real PL/pgSQL behaviour against a live PostgreSQL instance. Each test runs inside a transaction that is rolled back on teardown, so nothing is left in the database after the suite finishes. These tests require DATABASE_URL to be set; they skip automatically when it is absent.

tests/migrations/

pytest-alembic tests that verify the migration history is consistent and round-trips cleanly.

For fast feedback during development, run pytest directly:

just dev-test

To run the full test suite with tox (installs the package into a clean environment, matching what CI does):

just test

Both commands pass arguments through to pytest:

just dev-test tests/unit
just dev-test tests/integration
just dev-test -k test_shoot
just test tests/unit

Note

Integration tests require a PostgreSQL instance. Set DATABASE_URL before running them, for example:

DATABASE_URL=postgresql+psycopg://postgres@localhost/codegen_database just dev-test tests/integration

Coverage

codegen_database uses slipcover for coverage reporting:

just coverage

This runs the full pytest suite under slipcover and prints a per-file coverage table to the terminal. Pass any pytest arguments to narrow the scope:

just coverage tests/unit
just coverage tests/integration

Benchmarks

codegen_database ships with a performance benchmark suite built on pytest-benchmark. Benchmarks exercise the trigger-based dimension views for each dimension type against a real PostgreSQL instance.

Benchmarks are excluded from normal test runs (just dev-test and just test) via the addopts = "--ignore=tests/benchmarks" setting in pyproject.toml. Run them explicitly with:

just bench

You can pass any pytest-benchmark flags through:

# Save results for later comparison
just bench --benchmark-save=baseline

# Compare against a saved baseline
just bench --benchmark-compare=0001_baseline

# Only run ledger benchmarks
just bench -k ledger

Each benchmark row in the output table shows:

Column

Meaning

Min

Fastest observed round

Max

Slowest observed round

Mean

Arithmetic mean across all rounds

StdDev

Standard deviation (lower is more consistent)

Median

Middle value (robust to outliers)

Rounds

Number of times the function was called

To re-run benchmarks and update the documentation tables:

just bench-docs

This saves the JSON results and regenerates the RST included by Benchmarks.

Linting and formatting

codegen_database uses ruff for linting and formatting. It runs automatically as a pre-commit hook, but you can also run it manually:

just lint

Ruff will check for style issues and verify formatting. To auto-fix and auto-format:

uv run --group lint ruff check --fix
uv run --group lint ruff format

Type checking

codegen_database uses zuban for type checking:

just type-check

Documentation

The docs are built with Sphinx using the Furo theme.

The doc build generates schema diagrams and query examples from a live PostgreSQL database, so DATABASE_URL must be set. If it is not set, the build defaults to postgresql+psycopg:///codegen_database.

To build the docs:

just docs

To serve the docs locally with live reload at http://localhost:8000:

just serve-docs

Or with an explicit database URL:

DATABASE_URL=postgresql+psycopg://localhost/codegen_database just serve-docs

The docs will automatically rebuild whenever you save a file.

Commands reference

just bench <*args>

Performance benchmarks (requires DATABASE_URL).

just bench-docs

Run benchmarks and regenerate docs/benchmarks.rst.

just coverage <*args>

Coverage report (branch + line).

just coverage-ci <*args>

Coverage with XML output (CI gate).

just dev-test <*args>

Pytest directly via uv (faster local-dev loop).

just docs

Build HTML docs to docs/_build/html (sync + dynamic RST + sphinx-build).

just docs-check

Strict single-version docs build (CI gate; fails on any warning).

just serve-docs-autoreload

Serve docs with live reload for editing (http://127.0.0.1:8000).

just serve-docs-static

Serve the full versioned docs build (http://localhost:8000).

just sqlfluff <*flags>

SQL lint (sqlfluff). Pass --fix to auto-fix; bare is check-only.

just sync

Vendor / refresh the shared just modules.

just test <*args>

Run the full suite via tox (full isolation, builds sdist).

Contributing

Contributions are welcome. Fork the repository, make your changes with tests where applicable, verify the test suite and linter pass (see the sections above), then open a pull request against main.

Type annotations are required on all public API.

To report a bug, open a GitHub issue with a minimal reproduction case, what you expected, what happened, and your Python version and OS.

For security vulnerabilities, see SECURITY.md rather than opening a public issue.