Skip to main content

Generate goose-style SQL migrations from Django migrations, plus base model mixins

Project description

DJM

CLI and helpers to go from Django models → goose-style SQL migrations (up/down). One app (djm): write your models there, then generate SQL for goose or golang-migrate.

Quick start (CLI)

  1. Install and create a project:

    pip install djm
    djm init myapp
    cd myapp
    
  2. Write your models in the djm app (edit djm/models/), then run migrations:

    uv sync   # or: pip install -e .
    uv run python manage.py makemigrations djm
    uv run python manage.py migrate
    
  3. Generate goose SQL (up/down) into goose_migrations/:

    uv run python manage.py generate_goose
    

    From a project that has the djm CLI installed you can instead run:

    djm goose
    
  4. Use the generated .sql files with goose or golang-migrate.

Requirements

  • Python ≥3.13 (or adjust in pyproject.toml)
  • Django ≥6.0
  • uv (recommended) or pip

CLI

Command Description
djm init [path] Create a new DJM project (default: current directory). Preconfigured with djm app and generate_goose command.
djm goose [-o DIR] Generate goose SQL migrations (run from project root; uses manage.py generate_goose).

Project layout (after djm init)

Path Purpose
djm/ The only app: write your models here. Includes the generate_goose management command.
base/ Reusable abstract model mixins: UUIDPrimaryKeyMixin, TimestampsMixin, SoftDeleteMixin, SortNumberMixin.
core/ Main Django project (settings, urls).

Commands (inside a project)

  • Generate goose migrations:
    uv run python manage.py generate_goose [--output-dir DIR] [--no-sql-extension]
    
    Uses the djm app. Default output dir is goose_migrations. Files are named {migration_name}.sql.

Base mixins

Use these in your models (see djm.models and base.models):

  • UUIDPrimaryKeyMixin – UUID primary key (via uuid6).
  • TimestampsMixincreated, updated (auto_now_add / auto_now).
  • SoftDeleteMixindeleted nullable datetime for soft deletes.
  • SortNumberMixinorder_no and default ordering.

Import from base.models; the mixins are abstract and do not require base in INSTALLED_APPS unless you add migrations in base.

Shipping as a package

The package ships djm (models + generate_goose command) and base (mixins). One app only; users write models in djm.

  • Install: pip install -e /path/to/djm or pip install djm
  • In the consuming project: Add djm to INSTALLED_APPS, write models in djm, run python manage.py generate_goose -o your_goose_dir.
  • Build: make build or uv build

Publishing to PyPI (GitHub Actions)

The repo includes a workflow that builds and publishes to PyPI when you create a GitHub Release (or run it manually from the Actions tab).

  1. One-time: Add a trusted publisher on PyPI:

    • PyPI project name: djm
    • Repository: OWNER/djm
    • Workflow name: publish.yml
  2. To release: Create a new release on GitHub (tag, e.g. v0.1.0). The workflow will build and publish the package to PyPI. No API token is needed (OIDC).

  • .github/workflows/publish.yml – build + publish to PyPI on release
  • .github/workflows/ci.yml – build only on push/PR to main

Makefile

  • make help – show targets
  • make migrate – run Django migrations
  • make goose – generate goose SQL into goose_migrations
  • make goose OUT=./sql – generate into ./sql
  • make clean – remove generated goose files and __pycache__
  • make installuv sync
  • make build – build distribution artifacts

Notes

  • Django’s sqlmigrate supports --backwards (with an “s”) to print SQL that unapplies a migration; the generator uses this for the “Down” section.
  • Generated SQL is for the database configured in settings.DATABASES["default"] (e.g. SQLite). For PostgreSQL/MySQL, run the generator with that database configured.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

djm-0.0.1a0.tar.gz (10.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

djm-0.0.1a0-py3-none-any.whl (17.5 kB view details)

Uploaded Python 3

File details

Details for the file djm-0.0.1a0.tar.gz.

File metadata

  • Download URL: djm-0.0.1a0.tar.gz
  • Upload date:
  • Size: 10.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.12.8

File hashes

Hashes for djm-0.0.1a0.tar.gz
Algorithm Hash digest
SHA256 fe492e6f96ca962e6ea9dd42da2c01bfd5ef6a0c8e9fd99c689207bf0916d29f
MD5 7a24395bc1297bf9bb3c9057fd2de56b
BLAKE2b-256 1d74f45ccdeffce78761a047bd8547c98ce85ab9d017f6608ee1f01b64d42b10

See more details on using hashes here.

Provenance

The following attestation bundles were made for djm-0.0.1a0.tar.gz:

Publisher: publish.yml on dcostersabin/djm

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file djm-0.0.1a0-py3-none-any.whl.

File metadata

  • Download URL: djm-0.0.1a0-py3-none-any.whl
  • Upload date:
  • Size: 17.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.12.8

File hashes

Hashes for djm-0.0.1a0-py3-none-any.whl
Algorithm Hash digest
SHA256 05cad7051785d21754f64f2c55ea1b114b91ab29181f51deed42b9504dcdd4fd
MD5 13a163a52b559a58244e24cfb9682eaa
BLAKE2b-256 78331be39a3cf8007b4f43d9dc1a272e4053fa74febdb8649a47295c3d5e08ea

See more details on using hashes here.

Provenance

The following attestation bundles were made for djm-0.0.1a0-py3-none-any.whl:

Publisher: publish.yml on dcostersabin/djm

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page