Skip to main content

PostgreSQL schema evolution with built-in multi-agent coordination 🍓

Project description

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, status, baseline, and preflight are the migration runner — they don't require a db/schema/ directory. 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]"
      - run: confiture migrate up -c db/environments/production.yaml
        env:
          DATABASE_URL: ${{ secrets.PROD_DATABASE_URL }}

Exit codes: 0 success, 2 config error, 3 SQL failure, 6 lock contention, 7 structural drift. See the dry-run guide for what each one means.


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.
  • 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. 🍓→🍯

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

fraiseql_confiture-0.17.0.tar.gz (1.8 MB view details)

Uploaded Source

Built Distributions

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

fraiseql_confiture-0.17.0-cp314-cp314-win_amd64.whl (899.6 kB view details)

Uploaded CPython 3.14Windows x86-64

fraiseql_confiture-0.17.0-cp313-cp313-win_amd64.whl (899.6 kB view details)

Uploaded CPython 3.13Windows x86-64

fraiseql_confiture-0.17.0-cp313-cp313-manylinux_2_28_x86_64.whl (991.7 kB view details)

Uploaded CPython 3.13manylinux: glibc 2.28+ x86-64

fraiseql_confiture-0.17.0-cp313-cp313-macosx_11_0_arm64.whl (946.1 kB view details)

Uploaded CPython 3.13macOS 11.0+ ARM64

fraiseql_confiture-0.17.0-cp312-cp312-win_amd64.whl (899.7 kB view details)

Uploaded CPython 3.12Windows x86-64

fraiseql_confiture-0.17.0-cp312-cp312-manylinux_2_28_x86_64.whl (991.9 kB view details)

Uploaded CPython 3.12manylinux: glibc 2.28+ x86-64

fraiseql_confiture-0.17.0-cp312-cp312-macosx_11_0_arm64.whl (946.1 kB view details)

Uploaded CPython 3.12macOS 11.0+ ARM64

fraiseql_confiture-0.17.0-cp311-cp311-win_amd64.whl (899.5 kB view details)

Uploaded CPython 3.11Windows x86-64

fraiseql_confiture-0.17.0-cp311-cp311-manylinux_2_28_x86_64.whl (993.3 kB view details)

Uploaded CPython 3.11manylinux: glibc 2.28+ x86-64

fraiseql_confiture-0.17.0-cp311-cp311-macosx_11_0_arm64.whl (946.4 kB view details)

Uploaded CPython 3.11macOS 11.0+ ARM64

File details

Details for the file fraiseql_confiture-0.17.0.tar.gz.

File metadata

  • Download URL: fraiseql_confiture-0.17.0.tar.gz
  • Upload date:
  • Size: 1.8 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.16 {"installer":{"name":"uv","version":"0.11.16","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}

File hashes

Hashes for fraiseql_confiture-0.17.0.tar.gz
Algorithm Hash digest
SHA256 67190d26089964742733a18578632d39596cc8008c6ad63e241ad4e15b487df5
MD5 249cfac37ad2829fac3c9c1a29282dca
BLAKE2b-256 1c665601f23d2076d2154010533da9714a5e8c66bd6f12cdf14b5dba91190310

See more details on using hashes here.

File details

Details for the file fraiseql_confiture-0.17.0-cp314-cp314-win_amd64.whl.

File metadata

  • Download URL: fraiseql_confiture-0.17.0-cp314-cp314-win_amd64.whl
  • Upload date:
  • Size: 899.6 kB
  • Tags: CPython 3.14, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.16 {"installer":{"name":"uv","version":"0.11.16","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}

File hashes

Hashes for fraiseql_confiture-0.17.0-cp314-cp314-win_amd64.whl
Algorithm Hash digest
SHA256 c22da3d3767cf9f17cc339a245eba046fc10c22870ec7cde5e655548891d53d6
MD5 5e305cfeb1f21dbd403a940998ef438b
BLAKE2b-256 24175869861ef5d46615ec223a72a20d2b94130d0651c7e1af09a235fe46f8e2

See more details on using hashes here.

File details

Details for the file fraiseql_confiture-0.17.0-cp313-cp313-win_amd64.whl.

File metadata

  • Download URL: fraiseql_confiture-0.17.0-cp313-cp313-win_amd64.whl
  • Upload date:
  • Size: 899.6 kB
  • Tags: CPython 3.13, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.16 {"installer":{"name":"uv","version":"0.11.16","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}

File hashes

Hashes for fraiseql_confiture-0.17.0-cp313-cp313-win_amd64.whl
Algorithm Hash digest
SHA256 4b69a23fea5768fb568b8410cccd0f0f38d105ed8fce7e27cb5adff7b039fcc8
MD5 7c90d96819b19c6b6aa5ca482d7234db
BLAKE2b-256 791158d906c92e42568ad99f623ffb184828bc6da78ae01490aa5a18b9b4d57e

See more details on using hashes here.

File details

Details for the file fraiseql_confiture-0.17.0-cp313-cp313-manylinux_2_28_x86_64.whl.

File metadata

  • Download URL: fraiseql_confiture-0.17.0-cp313-cp313-manylinux_2_28_x86_64.whl
  • Upload date:
  • Size: 991.7 kB
  • Tags: CPython 3.13, manylinux: glibc 2.28+ x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.16 {"installer":{"name":"uv","version":"0.11.16","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}

File hashes

Hashes for fraiseql_confiture-0.17.0-cp313-cp313-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 4c8dcc6f4d246d3501a79252cf80e7263d9418061ea66a3c3900785b795e9dcc
MD5 024afe9e87db50ad28573841e2038b4d
BLAKE2b-256 72c8e84817c3bc08e9b2ee82524e69a85d4c527ac65e2d2b245e93ec36259096

See more details on using hashes here.

File details

Details for the file fraiseql_confiture-0.17.0-cp313-cp313-macosx_11_0_arm64.whl.

File metadata

  • Download URL: fraiseql_confiture-0.17.0-cp313-cp313-macosx_11_0_arm64.whl
  • Upload date:
  • Size: 946.1 kB
  • Tags: CPython 3.13, macOS 11.0+ ARM64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.16 {"installer":{"name":"uv","version":"0.11.16","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}

File hashes

Hashes for fraiseql_confiture-0.17.0-cp313-cp313-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 ead3aa190736fc5edfb94ac86cc44aa694f276f598e5207ec8a993aaad12c459
MD5 e384a2924b5ee1479178f16b68315fd8
BLAKE2b-256 05d10be3ee1b87bb12a47ed284ffd5ecab3540f2d7c5a7e757b6ccfd00a3654f

See more details on using hashes here.

File details

Details for the file fraiseql_confiture-0.17.0-cp312-cp312-win_amd64.whl.

File metadata

  • Download URL: fraiseql_confiture-0.17.0-cp312-cp312-win_amd64.whl
  • Upload date:
  • Size: 899.7 kB
  • Tags: CPython 3.12, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.16 {"installer":{"name":"uv","version":"0.11.16","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}

File hashes

Hashes for fraiseql_confiture-0.17.0-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 6f4e3c46e3c6079c7adcdab32052717b1bbb81dae8db72f5fae64d4f92480fc8
MD5 462be5ab99ce49d569d000b27c5eb863
BLAKE2b-256 350ef8d841a12cc91b8fb8881c8d60970324366ac5d240dbe51b43242cf8efb6

See more details on using hashes here.

File details

Details for the file fraiseql_confiture-0.17.0-cp312-cp312-manylinux_2_28_x86_64.whl.

File metadata

  • Download URL: fraiseql_confiture-0.17.0-cp312-cp312-manylinux_2_28_x86_64.whl
  • Upload date:
  • Size: 991.9 kB
  • Tags: CPython 3.12, manylinux: glibc 2.28+ x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.16 {"installer":{"name":"uv","version":"0.11.16","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}

File hashes

Hashes for fraiseql_confiture-0.17.0-cp312-cp312-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 13f143db8b76107eaf8611efcaad1366673e547de35da398929e77a2c3abf68f
MD5 485ce4ed2e028340b05d02bb5848aae3
BLAKE2b-256 5c10e2f9b6c782740dff81256b6c22ebf65d16a8f5e44191af14b7dbc2f72f3f

See more details on using hashes here.

File details

Details for the file fraiseql_confiture-0.17.0-cp312-cp312-macosx_11_0_arm64.whl.

File metadata

  • Download URL: fraiseql_confiture-0.17.0-cp312-cp312-macosx_11_0_arm64.whl
  • Upload date:
  • Size: 946.1 kB
  • Tags: CPython 3.12, macOS 11.0+ ARM64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.16 {"installer":{"name":"uv","version":"0.11.16","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}

File hashes

Hashes for fraiseql_confiture-0.17.0-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 7a617498c8b9d594453d72f0b815a6745d0ad3a6bfe38e896140dfbc5a7b58b8
MD5 5f9002fbcb7eaa6c164a7478d2277a00
BLAKE2b-256 58c295e8be08f2a67d5aacd2e5edff3bce5438aaf41358b2063b1f73b969e5c5

See more details on using hashes here.

File details

Details for the file fraiseql_confiture-0.17.0-cp311-cp311-win_amd64.whl.

File metadata

  • Download URL: fraiseql_confiture-0.17.0-cp311-cp311-win_amd64.whl
  • Upload date:
  • Size: 899.5 kB
  • Tags: CPython 3.11, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.16 {"installer":{"name":"uv","version":"0.11.16","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}

File hashes

Hashes for fraiseql_confiture-0.17.0-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 211b0bf16eb50f6a977499448a1e42598c71b3025eb47d7d136b3477969e0d84
MD5 844a4a218d539e61f3908e6257f1955f
BLAKE2b-256 8aa8d9f11bf719220e54076b5c1044bbee7da32252d77cbb586e3e4887b0611b

See more details on using hashes here.

File details

Details for the file fraiseql_confiture-0.17.0-cp311-cp311-manylinux_2_28_x86_64.whl.

File metadata

  • Download URL: fraiseql_confiture-0.17.0-cp311-cp311-manylinux_2_28_x86_64.whl
  • Upload date:
  • Size: 993.3 kB
  • Tags: CPython 3.11, manylinux: glibc 2.28+ x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.16 {"installer":{"name":"uv","version":"0.11.16","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}

File hashes

Hashes for fraiseql_confiture-0.17.0-cp311-cp311-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 878f8d151eeb65c3782f02a21db5392a28971c3d931321ab2c1c32711bfcdf9b
MD5 1e1febbdc619247d14a1cc87802974e0
BLAKE2b-256 4a999a8cb057adc5427e3e61d3c4d3377f6d452fc1d20c22a4d8df14ea29cd55

See more details on using hashes here.

File details

Details for the file fraiseql_confiture-0.17.0-cp311-cp311-macosx_11_0_arm64.whl.

File metadata

  • Download URL: fraiseql_confiture-0.17.0-cp311-cp311-macosx_11_0_arm64.whl
  • Upload date:
  • Size: 946.4 kB
  • Tags: CPython 3.11, macOS 11.0+ ARM64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.16 {"installer":{"name":"uv","version":"0.11.16","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}

File hashes

Hashes for fraiseql_confiture-0.17.0-cp311-cp311-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 6f0f0b0dfdd86c76228fa781936918946458f9d350a4b43528000efdde385482
MD5 387a7247579778d57969225b9fb2d991
BLAKE2b-256 e380c7102c6011a8b0b14c8162ba88ce5f6432c41bc0e663b33276b5832b9401

See more details on using hashes here.

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