Skip to main content

Confiture 🍓

PostgreSQL migrations, sweetly done.

Build from DDL. Adopt on day one against a database that already has migrations applied. Preflight every deploy against a parallel database with structural diff. Sync production data with PII anonymization.

PyPI Quality Gate Python 3.11+ PostgreSQL 12+ License: MIT


In 30 seconds

# 1. You already have a database at migration 004 (applied by hand or by another tool).
#    Tell Confiture about that history without re-running the SQL:
$ confiture migrate baseline --through 004 -c db/environments/production.yaml
  ✅ 001 create_users (marked as applied)
  ✅ 002 create_orders (marked as applied)
  ✅ 003 add_user_email (marked as applied)
  ✅ 004 add_user_preferences (marked as applied)
✅ Marked 4 migration(s) as applied, skipped 0 already applied

# 2. Machine-readable proof that the tracking is healthy:
$ confiture migrate status -c db/environments/production.yaml --format json | jq '.applied | length'
4

# 3. Preflight: replay pending migrations on a parallel DB, emit a structural diff vs. db/schema/.
$ confiture migrate preflight --against "$PREFLIGHT_URL" -c db/environments/production.yaml
▸ Replaying pending migrations on preflight DB …
  ✓ 20260520143015_add_user_bio                 applied in 24 ms
▸ Comparing resulting schema vs. db/schema/ …
  ✓ No drift — preflight matches db/schema/
✓ Preflight passed. Safe to deploy.
exit 0

That's the loop. Baseline once → status to confirm → preflight every deploy.


Already have migrations?

The single biggest reason migration tools fail adoption is the day-one cliff: existing tables already exist, so any tool that tries to apply migrations from scratch crashes on the first CREATE TABLE. Confiture's answer is migrate baseline:

confiture migrate baseline --through <last-applied-version>

The walkthrough — including failure modes, the integration test that backs the recipe, and what tb_confiture ends up looking like — is in docs/guides/legacy-bootstrap.md.


No db/schema/ directory? That works too.

confiture migrate up, down, down-to, status, current, baseline, and preflight are the migration runner — they don't require a db/schema/ directory (migrate current prints the latest applied revision as a narrow "what's deployed?" contract; migrate down --steps N rolls back relatively while migrate down-to <revision> rolls back to a specific revision, refusing atomically if any required .down.sql is missing). The "Build from DDL" pitch above the fold sells one of confiture's four strategies; the other three (incremental migrations, production sync, schema-to-schema FDW migration) work against a project whose only source of truth is the migration chain itself.

If you're evaluating confiture against Flyway / Alembic / dbmate / sqlx-cli as a pure migration runner, skip confiture build and use everything else. Walkthrough: docs/guides/02-incremental-migrations.md.


When to use Confiture?

Capability Confiture Flyway Alembic dbmate sqlx-cli plain psql
Source of truth DDL files or migration chain migration chain model classes migration chain migration chain DDL files
Tracking table yes yes yes yes yes no
Rollback (down.sql) yes paid yes yes yes no
Preflight against a copy DB yes (structural diff) no no no no no
Build from scratch in <1s yes no no no no yes (manual)
Production sync + anonymization yes no no no no no
Zero-downtime via FDW yes no no no no no
Multi-agent coordination yes no no no no no
Ecosystem maturity / stars early very mature mature mature mature n/a

Note on "source of truth": confiture can run as a pure migration tool against a project that has no db/schema/ directory — the DDL workflow is opt-in. See No db/schema/ directory? above.

Confiture wins on build-from-DDL, structural-diff preflight, production sync, and multi-agent coordination. It loses on ecosystem age — Flyway and Alembic have a decade of community knowledge. Pick honestly.

Adoption checklist

Situation Recommended tool
1 environment + 1 contributor, schema rarely changes plain psql
2+ environments, schema changes weekly Confiture, Flyway, Alembic, or dbmate
Multi-agent / AI-driven development on shared schemas Confiture
You have a migration chain (no db/schema/) and want preflight + tracking Confiture (use everything except confiture build)
You want db/schema/ to be source of truth, not a migration chain Confiture
You need zero-downtime schema swaps with postgres_fdw Confiture (Medium 4)
You're committed to SQLAlchemy ORM Alembic
You're committed to a JVM stack Flyway

CI integration

A migrate preflight gate on every PR, a migrate up step on deploy. Exit codes are semantic, so the CI configuration stays simple:

# .github/workflows/db.yml
name: DB

on:
  pull_request:
    paths:
      - 'db/**'
  push:
    branches: [main]

jobs:
  preflight:
    if: github.event_name == 'pull_request'
    runs-on: ubuntu-latest
    services:
      postgres:
        image: postgres:16
        env: { POSTGRES_PASSWORD: x }
        ports: ['5432:5432']
        options: >-
          --health-cmd pg_isready --health-interval 10s
          --health-timeout 5s --health-retries 5
    steps:
      - uses: actions/checkout@v4
      - uses: astral-sh/setup-uv@v3
      - run: uv pip install --system "fraiseql-confiture[ast]"
      - name: Restore production snapshot to preflight DB
        run: ./scripts/restore-snapshot.sh   # your own; pg_restore from S3/GCS
      - name: Confiture preflight
        env:
          PREFLIGHT_URL: postgresql://postgres:x@localhost:5432/preflight
        run: |
          confiture migrate preflight \
            --against "$PREFLIGHT_URL" \
            -c db/environments/preflight.yaml \
            --format json --output preflight.json
      - uses: actions/upload-artifact@v4
        with:
          name: preflight-report
          path: preflight.json

  deploy:
    if: github.ref == 'refs/heads/main'
    runs-on: ubuntu-latest
    environment: production
    steps:
      - uses: actions/checkout@v4
      - uses: astral-sh/setup-uv@v3
      - run: uv pip install --system "fraiseql-confiture[ast]"
      # No YAML needed in CI — the migrate family reads DATABASE_URL directly
      # (or pass --database-url "$DSN"). See the connection-source docs below.
      - run: confiture migrate up
        env:
          DATABASE_URL: ${{ secrets.PROD_DATABASE_URL }}

migrate up/down/status/verify/preflight accept --database-url <dsn> (or read CONFITURE_DATABASE_URL / DATABASE_URL) so runtime-resolved DSNs need no temp YAML — precedence and details in the CLI reference.

Exit codes are a documented stability contract — see the exit-code reference. The most operationally important: 2 tracking table absent, 3 DB connection failed, 5 config invalid, 6 lock contention. For migrate preflight's drift-gate codes specifically, see the dry-run guide.

Migrations that open their own SAVEPOINTs, use psycopg's conn.transaction(), or wrap DO $$ … EXCEPTION WHEN … $$ blocks are supported under all three modes. The rules a migration body must follow for the SAVEPOINT-based rollback to stay clean are documented in the transaction & SAVEPOINT contract.


Python project snippet

Add Confiture as a dev dependency. The [ast] extra pulls in pglast for full PostgreSQL parsing — recommended for schemas with bulk seed data.

# pyproject.toml
[dependency-groups]
dev = [
  "fraiseql-confiture[ast]>=0.9",
  "pytest>=8",
]
# justfile
default:
    just --list

db-build:
    confiture build --env local

db-up:
    confiture migrate up

db-status:
    confiture migrate status

db-preflight:
    confiture migrate preflight --against "$PREFLIGHT_URL"

Or as a Makefile:

db-build:
	confiture build --env local

db-up:
	confiture migrate up

db-status:
	confiture migrate status

Library API

Confiture is a CLI first, but the migrator is fully usable from Python:

from confiture import Migrator

with Migrator.from_config("db/environments/prod.yaml") as m:
    status = m.status()
    if status.has_pending:
        result = m.up()
        print(f"Applied {len(result.applied)} migrations")

The Four Strategies

Strategy Use Case Command
Build from DDL Fresh databases, testing, CI confiture build --env local
Incremental Migrations Existing databases, production confiture migrate up
Production Sync Copy data with PII anonymization confiture sync --from prod --anonymize users.email
Zero-Downtime Complex migrations via FDW confiture migrate schema-to-schema

Documentation

Start here

Guides

Reference

For agents and tooling

  • Every machine-readable CLI output has a published JSON schema under docs/reference/json-schemas/ — see docs/reference/json-schemas.md.
  • On an error path in --format json mode, the migrate family emits a structured error envelope on stdout — {"ok": false, "error": {code, message, severity, actionable, details, migration, file, line}} — and exits with the exit code for that error. The full code list and the envelope schema are in the error-code codebook.
  • confiture migrate validate --list-patterns --format json exposes the full idempotency-detection catalog (read-only, no DB / config / migrations directory needed).
  • Quiet-success ambiguities surface advisory hints in payload["hints"] (or on stderr in text mode) — exit codes are unaffected.

Contributing

git clone https://github.com/fraiseql/confiture.git
cd confiture
uv sync --all-extras
uv run pytest

See CONTRIBUTING.md and CLAUDE.md.


Author & License

Vibe-engineered by Lionel Hamayon 🍓

MIT License — Copyright (c) 2025 Lionel Hamayon


Making jam from strawberries, one migration at a time. 🍓→🍯

Release files for fraiseql-confiture 0.43.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 fraiseql-confiture 0.43.0
File Size Uploaded
fraiseql_confiture-0.43.0.tar.gz 2.4 MB Details

Built distributions (wheels)

Table of built distributions (wheels) for fraiseql-confiture 0.43.0
File
fraiseql_confiture-0.43.0-cp314-cp314-win_amd64.whl CPython 3.14 CPython 3.14 Windows x86-64 Details
fraiseql_confiture-0.43.0-cp313-cp313-win_amd64.whl CPython 3.13 CPython 3.13 Windows x86-64 Details
fraiseql_confiture-0.43.0-cp313-cp313-manylinux_2_28_x86_64.whl CPython 3.13 CPython 3.13 Linux glibc 2.28+ x86-64 Details
fraiseql_confiture-0.43.0-cp313-cp313-macosx_11_0_arm64.whl CPython 3.13 CPython 3.13 macOS 11.0+ ARM64 Details
fraiseql_confiture-0.43.0-cp312-cp312-win_amd64.whl CPython 3.12 CPython 3.12 Windows x86-64 Details
fraiseql_confiture-0.43.0-cp312-cp312-manylinux_2_28_x86_64.whl CPython 3.12 CPython 3.12 Linux glibc 2.28+ x86-64 Details
fraiseql_confiture-0.43.0-cp312-cp312-macosx_11_0_arm64.whl CPython 3.12 CPython 3.12 macOS 11.0+ ARM64 Details
fraiseql_confiture-0.43.0-cp311-cp311-win_amd64.whl CPython 3.11 CPython 3.11 Windows x86-64 Details
fraiseql_confiture-0.43.0-cp311-cp311-manylinux_2_28_x86_64.whl CPython 3.11 CPython 3.11 Linux glibc 2.28+ x86-64 Details
fraiseql_confiture-0.43.0-cp311-cp311-macosx_11_0_arm64.whl CPython 3.11 CPython 3.11 macOS 11.0+ ARM64 Details

Total release size: 13.4 MB

Release files / fraiseql_confiture-0.43.0.tar.gz

Download URL fraiseql_confiture-0.43.0.tar.gz
Size 2.4 MB
Tags Source
SHA-256 checksum
How to use checksums
550873be19ff753b7e09828e096b785d2a08498f812bcb0153a6beed444cf57c
BLAKE2b-256 checksum
How to use checksums
afe49a57d56281ecd0676453e164c327e2b949511592cf785627454062a14c14
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.2 {"installer":{"name":"uv","version":"0.12.2","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / fraiseql_confiture-0.43.0-cp314-cp314-win_amd64.whl

Download URL fraiseql_confiture-0.43.0-cp314-cp314-win_amd64.whl
Size 1.1 MB
Tags CPython 3.14 Windows x86-64
SHA-256 checksum
How to use checksums
b26b84b4160faa86a885780c8059b104c2b39a22d5f0c9ab05370f8b32698a89
BLAKE2b-256 checksum
How to use checksums
76ec40606b02108a0bdc94b348f8b476d3bee125bd6e7689e86a98a97b03863c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.2 {"installer":{"name":"uv","version":"0.12.2","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / fraiseql_confiture-0.43.0-cp313-cp313-win_amd64.whl

Download URL fraiseql_confiture-0.43.0-cp313-cp313-win_amd64.whl
Size 1.1 MB
Tags CPython 3.13 Windows x86-64
SHA-256 checksum
How to use checksums
45f247b2d937174f6b0bdb562bebe7d7ba02e2bcabb9e76734c9d978a191364b
BLAKE2b-256 checksum
How to use checksums
725aadb0d7016cea181fda3954953d66678d83c776b5dc83d7319106ecf62332
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.2 {"installer":{"name":"uv","version":"0.12.2","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / fraiseql_confiture-0.43.0-cp313-cp313-manylinux_2_28_x86_64.whl

Download URL fraiseql_confiture-0.43.0-cp313-cp313-manylinux_2_28_x86_64.whl
Size 1.2 MB
Tags CPython 3.13 Linux glibc 2.28+ x86-64
SHA-256 checksum
How to use checksums
0ec0403ea2bb0863cef1379d08620927a040c918b1b89311671091ef8f36fe26
BLAKE2b-256 checksum
How to use checksums
77fa770af55812bd2c336c200bccc09b2f292089b71ebe006b2146659dbcfd44
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.2 {"installer":{"name":"uv","version":"0.12.2","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / fraiseql_confiture-0.43.0-cp313-cp313-macosx_11_0_arm64.whl

Download URL fraiseql_confiture-0.43.0-cp313-cp313-macosx_11_0_arm64.whl
Size 1.1 MB
Tags CPython 3.13 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
680b2233781bb1bda2e3c5f112b1ce692b6eced01ccbb3342642993efb6c6081
BLAKE2b-256 checksum
How to use checksums
a2272a3da5de479b9d8bbf135c77d9101806f19a39a33d0eefc6cda0b0e97b3f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.2 {"installer":{"name":"uv","version":"0.12.2","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / fraiseql_confiture-0.43.0-cp312-cp312-win_amd64.whl

Download URL fraiseql_confiture-0.43.0-cp312-cp312-win_amd64.whl
Size 1.1 MB
Tags CPython 3.12 Windows x86-64
SHA-256 checksum
How to use checksums
46bd1d3c8f7b9bf35cb6ca188dd2401e0e50270dda8752d5b3bf1e17d78aa91c
BLAKE2b-256 checksum
How to use checksums
957944a946f3852edbe331cf5556c32701d1163f7e7ef4865f583b555b5f1b34
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.2 {"installer":{"name":"uv","version":"0.12.2","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / fraiseql_confiture-0.43.0-cp312-cp312-manylinux_2_28_x86_64.whl

Download URL fraiseql_confiture-0.43.0-cp312-cp312-manylinux_2_28_x86_64.whl
Size 1.2 MB
Tags CPython 3.12 Linux glibc 2.28+ x86-64
SHA-256 checksum
How to use checksums
37ec327f70fbfdad4cc398d99223d7ea55f7cdf8a451ca23be35341d602a0e5e
BLAKE2b-256 checksum
How to use checksums
89e44795d74b6ad05e677a2f54001214e3bc58720b69c12163b86ebc277d84f3
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.2 {"installer":{"name":"uv","version":"0.12.2","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / fraiseql_confiture-0.43.0-cp312-cp312-macosx_11_0_arm64.whl

Download URL fraiseql_confiture-0.43.0-cp312-cp312-macosx_11_0_arm64.whl
Size 1.1 MB
Tags CPython 3.12 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
68fc0370acb760ec19dac174949ce49d24336ea7b2cce5c1f892cac1063b4c87
BLAKE2b-256 checksum
How to use checksums
ea0b34c2851ca01bfa5f0c29b0fd71e8c51b5073b31e5e1592af12e398486f34
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.2 {"installer":{"name":"uv","version":"0.12.2","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / fraiseql_confiture-0.43.0-cp311-cp311-win_amd64.whl

Download URL fraiseql_confiture-0.43.0-cp311-cp311-win_amd64.whl
Size 1.1 MB
Tags CPython 3.11 Windows x86-64
SHA-256 checksum
How to use checksums
089f57d30419ece904ca97dfbc3a1f7d05dae84bb3f677cbddc0dace274d9aab
BLAKE2b-256 checksum
How to use checksums
9bf89fab6ec6524d2e33ebb9a1da43b193c9bad18e6b083ba7df06fd9626c6a4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.2 {"installer":{"name":"uv","version":"0.12.2","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / fraiseql_confiture-0.43.0-cp311-cp311-manylinux_2_28_x86_64.whl

Download URL fraiseql_confiture-0.43.0-cp311-cp311-manylinux_2_28_x86_64.whl
Size 1.2 MB
Tags CPython 3.11 Linux glibc 2.28+ x86-64
SHA-256 checksum
How to use checksums
49be786e3d832567471051104d84a8caf028498d0a859b17992f2d7c3589f8a1
BLAKE2b-256 checksum
How to use checksums
f92623971f23c3e0eea39672be3631a031580de32c0b92f6fac47c207f71d2e6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.2 {"installer":{"name":"uv","version":"0.12.2","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / fraiseql_confiture-0.43.0-cp311-cp311-macosx_11_0_arm64.whl

Download URL fraiseql_confiture-0.43.0-cp311-cp311-macosx_11_0_arm64.whl
Size 1.1 MB
Tags CPython 3.11 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
3081f55ec5044f6633de9976122050368e4aff92ab646f18064cba6c2a594090
BLAKE2b-256 checksum
How to use checksums
1fd3d2a1c3386395dcdc3d684f742a3ff85b33343ac743ff3550810e8f432b90
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.2 {"installer":{"name":"uv","version":"0.12.2","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release history Release notifications | RSS feed

1.9.1

11 release files

1.9.0

11 release files

1.6.0

11 release files

This release

0.43.0 This release

11 release files

0.9.5

11 release files

0.9.4

11 release files

0.9.3

11 release files

0.9.2

11 release files

0.9.0

11 release files

0.8.9

11 release files

0.8.8

11 release files

0.8.7

11 release files

0.8.6

11 release files

0.8.5

11 release files

0.8.4

11 release files

0.8.3

11 release files

0.8.2

11 release files

0.8.1

11 release files

0.6.2

11 release files

0.6.0

11 release files

0.5.9

11 release files

0.5.8

11 release files

0.5.7

11 release files

0.5.6

11 release files

0.5.5

11 release files

0.5.4

11 release files

0.5.2

11 release files

0.5.1

11 release files

0.5.0

11 release files

0.4.4

11 release files

0.4.3

11 release files

0.4.2

11 release files

0.3.9

11 release files

0.3.7

10 release files

0.3.6

10 release files

0.3.5

10 release files

0.3.4

10 release files

0.3.2

10 release files

0.3.1

10 release files

0.1.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