Skip to main content

MongoMig

PyPI Python CI License: MIT

Alembic-style schema evolution and migrations for MongoDB.

Change your models, see exactly what changed, generate a migration, review its impact, and run it safely. Built for Python services (FastAPI, Flask, workers) on PyMongo or Beanie.

$ mongomig diff
USERS
  + status: string = 'active'                    REQUIRES_DATA_MIGRATION  backfill existing documents with 'active'
  + age: int | null = None                       SAFE  defaults to None: existing documents need no backfill
  + given_name: string                           MANUAL_REVIEW  required, with no default: choose a value for existing documents
  - first_name                                   WARNING  removed from the model; existing data is kept (not deleted)
  + index users_email_unique (email ↑, unique)   WARNING  fails if existing documents contain duplicates

Possible rename: users.first_name → given_name (85% similar). If so, pass --rename users.first_name:given_name

$ mongomig revision --autogenerate -m "evolve users" --rename users.first_name:given_name
Generated b91baf4fd592 → migrations/versions/20260925_1115_b91baf4fd592_evolve_users.py

$ mongomig plan
b91baf4fd592  evolve users   Risk: HIGH
  users  rename_field  $rename first_name           ~4,218,901 docs · collection scan
  users  backfill      $set status                  ~4,218,901 docs · collection scan
  users  create_index  users_email_unique (unique)  4,218,901 docs
         ⚠ will fail: duplicate values exist, e.g. {'email': 'sam@example.com'}

$ mongomig upgrade

Why MongoMig

  • Autogenerate from your models: plain Pydantic (@collection) or Beanie documents, no extra declarations. Backfills with your defaults, renames, indexes, $jsonSchema validators.
  • Every change is classified: SAFE, WARNING, REQUIRES_DATA_MIGRATION or MANUAL_REVIEW. Risky changes become commented TODO(review) blocks, and data is never deleted automatically.
  • Deterministic diffs: models are compared with a committed schema snapshot rather than a sampled database, so results are the same on every machine and in CI.
  • Knows how you store data: model_dump() vs jsonable_encoder stores dates as different BSON types, and MongoMig warns about types PyMongo can't store.
  • Production-grade execution: distributed lock, batched operations with progress and ETA, retries, checkpoints so a failed migration resumes where it stopped (mongomig resume), transactions, checksums, confirmation before destructive migrations, and restorable backups.
  • See the impact first: plan / --dry-run estimate documents touched and collection scans, and predict unique-index failures and validator rejections against real data.
  • Catch drift: mongomig drift compares your models with the data actually stored. It reports missing fields, unexpected types (age: string in 5.7% of documents), unknown fields, and missing indexes or validators, with thresholds for CI or scheduled checks.
  • Built for CI: mongomig validate, --json output everywhere, documented exit codes.

Install

pip install mongomig            # add [beanie] for Beanie support

Python 3.11+, MongoDB 6.0+ (tested on 6.0, 7.0, 8.0).

Quick start

mongomig init                                   # mongomig.yaml + migrations/
export MONGODB_URI="mongodb://localhost:27017"
# register your models in migrations/env.py (see below), then:
mongomig revision --autogenerate -m "initial"   # new project
mongomig baseline                               # ...or an existing database
mongomig upgrade
# app/models.py
from pydantic import BaseModel
from mongomig import collection, Index

@collection("users", indexes=[Index("email", unique=True)])
class User(BaseModel):
    name: str
    email: str
    status: str = "active"
# migrations/env.py
from mongomig import MongoMetadata

import app.models  # noqa: F401

target_metadata = MongoMetadata.default(storage="python")   # or "json"; Beanie: register_beanie(...)

Everyday loop: edit models → mongomig diff → mongomig revision --autogenerate -m "..." → review and commit → CI mongomig validate → deploy mongomig plan + mongomig upgrade. On a schedule: mongomig drift --check.

$ mongomig drift
USERS  10,000 sampled of ~4,982,133 documents
  ✗ (index)           index users_email_unique (email ↑, unique) is not in the database
  ✗ age               expected int | null · observed string 5.70%  > 0.5%
  ✗ profile.verified  required by the model · missing in 10.1% of documents  > 0.5%
  ! nickname          not in the model · present in 0.36% of documents  ≤ 1%

Documentation

Examples: FastAPI + Pydantic · FastAPI + Beanie

Status

The MVP is complete (config, revisions, upgrade/downgrade, schema inspection, diff, autogenerate, plan/dry-run, locking, batching, backups, CI checks), plus drift detection, resumable migrations and transactions. Planned next: migration squashing.

Development

make install        # uv venv + editable install with dev extras
make mongo-up       # MongoDB 7 single-node replica set in Docker
make check          # ruff + mypy --strict + pytest

Integration tests skip when MongoDB isn't running. To test another MongoDB version, run MONGO_VERSION=8.0 make mongo-up.

Releasing

  1. Bump src/mongomig/_version.py and update CHANGELOG.md, then merge to main.
  2. Create a GitHub Release with tag v<version> and publish it. The release workflow checks the version, builds and smoke-tests the wheel, and publishes to PyPI via Trusted Publishing.

Contributing

Bug reports, ideas and pull requests are welcome. See CONTRIBUTING.md.

License

MIT

Metadata

Release files for mongomig 0.3.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 mongomig 0.3.0
File Size Uploaded
mongomig-0.3.0.tar.gz 163.6 kB Details

Built distribution (wheel)

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

Total release size: 293.8 kB

Release files / mongomig-0.3.0.tar.gz

Download URL mongomig-0.3.0.tar.gz
Size 163.6 kB
Tags Source
SHA-256 checksum
How to use checksums
0c5d990e5c1f7b079bec2ccc3feeceeb178753ecbf6548396eeb427c2ca4f75b
BLAKE2b-256 checksum
How to use checksums
bd5e44d6e20f5631dfb15506281e1a5acf25d3c0c27b06060036da4d009828b2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 3, 2026.

Transparency log

Release files / mongomig-0.3.0-py3-none-any.whl

Download URL mongomig-0.3.0-py3-none-any.whl
Size 130.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
7eb6653113cd0e2116441d2f146ccd7e2bb19bf0c38a6344dd67705c030fb8f5
BLAKE2b-256 checksum
How to use checksums
80abff879c6a6a58bb7a10ec138de2c3728758968a6befa5cd1cb43ab4d58208
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 3, 2026.

Transparency log
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