Skip to main content

migrolint

A framework-agnostic linter for your database migrations folder. It catches the boring, expensive mistakes that pass locally and only blow up when CI actually runs the migrations — duplicate version numbers, sequence gaps, and up migrations with no matching down. No database connection, no framework lock-in, zero dependencies (pure standard library).

pip install migrolint

migrolint                      # auto-detects ./migrations, db/migrations, ...
migrolint db/migrations --strict

The problem

Two developers branch off main, each adds 0007_add_index.sql, both merge. Now your migrations folder has two migrations claiming version 0007. Your runner picks one and silently skips the other — or aborts the whole deploy. This is a known, recurring failure in every sequence-numbered migration tool.

The existing linters (django-migration-linter, Flyway's own checks) are tied to one framework or need a live database. If you use raw SQL with goose, dbmate, golang-migrate, or a hand-rolled folder, there's nothing that just looks at the filenames and tells you they're sane. That's migrolint.

What it checks

Rule Severity Meaning
DUPE_NUM error two migrations share a version number (the merge-collision bug)
MISSING_DOWN warning an up migration has no matching down (only flagged if the project uses up/down splits)
SEQ_GAP warning a hole in an integer sequence — usually a deleted or un-merged migration
BAD_FORMAT warning a file whose name no known convention recognizes

Naming conventions it understands

migrolint reads version numbers out of the filename, across the conventions people actually use:

Convention Example
Flyway V1__init.sql, U1__undo.sql, R__refresh.sql, V1.1__patch.sql
golang-migrate / dbmate 0001_create_users.up.sql + 0001_create_users.down.sql
goose / Rails 20230101120000_create_users.sql (timestamp prefix)
minimalist 1_init.sql, 2-add-index.sql

Timestamp-style versions are recognized but exempt from SEQ_GAP (they're not meant to be contiguous). Well-known non-migration files (schema.rb, structure.sql, seeds.rb, …) and any non-migration extension are skipped.

Usage

migrolint                      # scan the first migrations dir it finds
migrolint db/migrations        # scan a specific dir
migrolint app/migrations svc/migrations   # scan several
migrolint --json               # machine-readable, for tooling
migrolint --strict             # warnings become errors (exit 1) — good for CI
migrolint --ext .sql,.py       # override which extensions count
migrolint --ignore baseline.sql,seed.sql

You can also run it as a module: python -m migrolint db/migrations.

As a pre-commit / CI gate

# .pre-commit-config.yaml
- repo: local
  hooks:
    - id: migrolint
      name: migrolint
      entry: migrolint --strict
      language: system
      pass_filenames: false
# GitHub Actions
- run: pipx run migrolint --strict

Example output

migrolint db/migrations (14 files, 12 migrations)

  ✗ DUPE_NUM     version 0007 used by 2 migrations:
       0007_add_index.up.sql
       0007_add_orders_fk.up.sql
  ⚠ MISSING_DOWN 0009_drop_legacy.up.sql — no matching .down file
  ⚠ SEQ_GAP      missing version(s): 5

1 error, 2 warnings.

Exit codes

Code Meaning
0 clean (or only warnings, without --strict)
1 errors found — or warnings, when --strict is set
2 usage / IO error (no migrations dir, unreadable path)

Also available for Node

Same checks, same flags: npx migrolint (source: migrolint). Both ports read filenames identically, so a mixed-language team gets the same verdict.

License

MIT

Metadata

Release files for migrolint 0.1.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 migrolint 0.1.0
File Size Uploaded Provenance Actions
migrolint-0.1.0.tar.gz 11.7 kB Without provenance Details for migrolint-0.1.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for migrolint 0.1.0
File Interpreter ABI Platform Actions
migrolint-0.1.0-py3-none-any.whl Python 3 none any Details for migrolint-0.1.0-py3-none-any.whl

Total release size: 22.0 kB

Release files / migrolint-0.1.0.tar.gz

Download URL migrolint-0.1.0.tar.gz
Size 11.7 kB
Tags Source
SHA-256 checksum
How to use checksums
2f9219829e8107170f416022f50f3c3e6a5afcf9c3b4d238642ce4eb2d2d0852
BLAKE2b-256 checksum
How to use checksums
17d5d4651e2cb85207e3fe78c8f0b31dbd698cfc52f4fa008362b52511dd90dc
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.11.7

Release files / migrolint-0.1.0-py3-none-any.whl

Download URL migrolint-0.1.0-py3-none-any.whl
Size 10.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
8545a7badb58b204e547931848ce322b7b28c799fa48f4b48e557e9011f4da2d
BLAKE2b-256 checksum
How to use checksums
5162dd053830d8564757395b9452fa59232fb3a0b612f6124e82ca56d7e6e177
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.11.7

Security for migrolint 0.1.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files No provenance

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