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:
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_URLto 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-docsRun 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 docsBuild HTML docs to docs/_build/html (sync + dynamic RST + sphinx-build).
just docs-checkStrict single-version docs build (CI gate; fails on any warning).
just serve-docs-autoreloadServe docs with live reload for editing (http://127.0.0.1:8000).
just serve-docs-staticServe the full versioned docs build (http://localhost:8000).
just sqlfluff <*flags>SQL lint (sqlfluff). Pass
--fixto auto-fix; bare is check-only.just syncVendor / 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.