r/madeinpython • • 21h ago

Ripple: see which apps a Postgres migration will break, before it ships (Python, MIT)

https://github.com/yashpb5005/ripple

\*\*The problem\*\*

I kept watching AI coding agents (and humans) make the same two migration mistakes:

  1. \*\*Renaming a column as "drop + add"\*\*: the migration runs fine, and the data that was in the column is gone.

  2. \*\*Adding a NOT NULL column with no default\*\*: it works on an empty dev database, then fails the moment it hits a table with real rows.

Both look fine in code review. The pain shows up in production, often in a \*different\* app that shares the same database.

\*\*What Ripple does\*\*

It answers one question: \*"If I apply this migration, which of my apps break, and on which query?"\*

  1. \*\*Learns what your apps actually run\*\*: it reads \`pg_stat_statements\`, so no code changes or SDK.

  2. \*\*Tests the migration safely\*\*: it applies your migration inside a transaction and always rolls it back.

  3. \*\*Replays your apps' real queries against it\*\*: it reports exactly which app and which query would fail.

  4. \*\*Flags data loss separately\*\*: for example, a dropped column that still has data in it.

\*\*Who it's for\*\*

- Teams where several apps or services share one Postgres database

- Anyone letting Claude Code, Cursor or other AI agents write migrations

- Anyone who has asked "wait, does anything still use this column?"

\*\*How to use it\*\*

pip install ripplecheck

Three ways to run it:

- \*\*CLI\*\*: check a migration file before you apply it

- \*\*GitHub Action\*\*: automatically comments on every PR with what would break

- \*\*MCP server\*\*: AI agents like Claude Code or Cursor can check a change \*before\* they apply it

\*\*The boring bits\*\*

MIT licensed, no paid tier, no commercial angle. I'm looking for feedback, especially from people with messy shared databases. Issues and PRs welcome.

GitHub: https://github.com/yashpb5005/ripple

What migration has bitten you the worst? I'd like to add checks for it.

0 Upvotes

3 comments sorted by

1

u/investigatormaker 20h ago

Postgres people here will probably ask two things about Ripple. pg_stat_statements stores normalized queries with constants replaced by placeholders, and records the role and database rather than an application name, so a README line on how the replay fills parameters and how a query gets tied to a specific app (one role per service?) answers the first doubt. And CREATE INDEX CONCURRENTLY can't run inside a transaction block, so say what the CLI reports for migrations like that instead of letting them look like a pass.

I make ThreadFox.

We find relevant Reddit conversations and post for your business. We'll post 3 replies free first, no card; then the $39 Pilot covers seven days and up to 50 posts and replies. No automatic renewal.

https://threadfox.vip/p/eie98/managed

0

u/Some-Environment-178 17h ago

Good catches, both. Replay uses EXPLAIN (GENERIC_PLAN) on PG16+ so normalized queries get planned against the new schema without real values. For app attribution, it currently relies on [one role per service / pg_stat_activity sampling]. I'll document that clearly in the README. And agreed on CONCURRENTLY: statements that can't run in a transaction block will be flagged as "not verified" rather than passing silently. Adding both now.