A comprehensive, ORM-agnostic database migration system with FastAPI integration, supporting PostgreSQL, MySQL, and SQLite
Project description
DB Migration Manager
A comprehensive, ORM-agnostic database migration system with FastAPI integration and Pydantic model support, supporting PostgreSQL, MySQL, and SQLite.
Features
- 🚀 Version Control: Track and apply database schema changes systematically
- 🔄 Auto-diff: Generate migrations automatically from schema differences
- ✨ Pydantic Support: Create migrations directly from Pydantic models
- ⏪ Rollback Support: Safely rollback migrations when needed
- 🌐 FastAPI Integration: REST API for migration management
- 🐳 Docker Support: Easy setup with Docker Compose
- 🗄️ Multiple Database Support: PostgreSQL, MySQL, SQLite adapters
- 🔒 Security: Parameterized queries prevent SQL injection
- 📝 Transaction Safety: Atomic migrations with automatic rollback on failure
- 🎯 Type Safety: Full type hints and mypy support
- 🧪 Testing: Comprehensive test suite
Installation
Basic Installation
pip install db-migration-manager
With Database-Specific Dependencies
# PostgreSQL support
pip install db-migration-manager[postgresql]
# MySQL support
pip install db-migration-manager[mysql]
# SQLite support
pip install db-migration-manager[sqlite]
# FastAPI integration
pip install db-migration-manager[fastapi]
# All dependencies
pip install db-migration-manager[all]
Quick Start
1. Basic Usage
import asyncio
from db_migration_manager import PostgreSQLAdapter, MigrationManager
async def main():
# Initialize database adapter
db_adapter = PostgreSQLAdapter("postgresql://user:pass@localhost/db")
# Create migration manager
manager = MigrationManager(db_adapter)
await manager.initialize()
# Create a migration
await manager.create_migration(
"create_users_table",
up_sql="""
CREATE TABLE users (
id SERIAL PRIMARY KEY,
email VARCHAR(255) UNIQUE NOT NULL,
name VARCHAR(255) NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)
""",
down_sql="DROP TABLE users"
)
# Apply migrations
results = await manager.migrate()
print(f"Applied {len(results)} migrations")
# Get status
status = await manager.get_migration_status()
print(f"Applied: {status['applied_count']}, Pending: {status['pending_count']}")
asyncio.run(main())
2. Pydantic Model Support
Define your database schema using Pydantic models:
from datetime import datetime
from typing import Optional
from pydantic import Field
from db_migration_manager import DatabaseModel, primary_key, unique_field, indexed_field
class User(DatabaseModel):
# Primary key with auto-increment
id: int = primary_key(default=None)
# Unique email field
email: str = unique_field(max_length=255)
# Username with unique constraint
username: str = db_field(unique=True, max_length=50)
# Full name
full_name: str = Field(..., max_length=255)
# Timestamps
created_at: datetime = Field(default_factory=datetime.now)
is_active: bool = Field(default=True)
class Config:
__table_name__ = "users"
# Create migration from models
import asyncio
from db_migration_manager import PostgreSQLAdapter, MigrationManager
async def create_migration_from_models():
db_adapter = PostgreSQLAdapter("postgresql://user:pass@localhost/db")
manager = MigrationManager(db_adapter)
await manager.initialize()
# Create migration from Pydantic models
filepath = await manager.create_migration_from_models(
name="create_user_table",
models=[User],
auto_diff=True # Automatically compare with previous schema
)
print(f"Created migration: {filepath}")
# Apply the migration
results = await manager.migrate()
print(f"Applied {len(results)} migrations")
asyncio.run(create_migration_from_models())
3. FastAPI Integration
from fastapi import FastAPI
from db_migration_manager import PostgreSQLAdapter, MigrationManager
from db_migration_manager.api import add_migration_routes
app = FastAPI()
# Initialize migration manager
db_adapter = PostgreSQLAdapter("postgresql://user:pass@localhost/db")
manager = MigrationManager(db_adapter)
# Add migration routes
add_migration_routes(app, manager)
# Your API endpoints...
@app.get("/")
async def root():
return {"message": "Hello World"}
# Available migration endpoints:
# GET /health - Health check
# GET /migrations/status - Migration status
# GET /migrations/pending - Pending migrations
# POST /migrations/migrate - Apply migrations
# POST /migrations/rollback - Rollback migrations
# POST /migrations/create - Create new migration
# POST /migrations/create-from-models - Create migration from Pydantic models
# POST /migrations/validate-models - Validate Pydantic models
# POST /migrations/show-sql - Show SQL for Pydantic model
4. CLI Usage
# Set database URL
export DATABASE_URL="postgresql://user:pass@localhost/db"
# Check migration status
db-migrate status
# Create a new migration
db-migrate create add_user_profile --up-sql "ALTER TABLE users ADD COLUMN profile TEXT"
# Apply pending migrations
db-migrate migrate
# Rollback to specific version
db-migrate rollback 20240101_120000
# Create migration from Pydantic models
db-migrate create-from-models create_users my_app.models
# Validate Pydantic models
db-migrate validate-models my_app.models
# Show SQL for a specific model
db-migrate show-sql User my_app.models --dialect postgresql
# Help
db-migrate --help
Database Adapters
PostgreSQL
from db_migration_manager import PostgreSQLAdapter
adapter = PostgreSQLAdapter("postgresql://user:pass@localhost:5432/dbname")
MySQL
from db_migration_manager import MySQLAdapter
adapter = MySQLAdapter({
'host': 'localhost',
'user': 'user',
'password': 'password',
'db': 'dbname',
'port': 3306
})
SQLite
from db_migration_manager import SQLiteAdapter
adapter = SQLiteAdapter("path/to/database.db")
Pydantic Model Annotations
The library provides special field annotations for database-specific features:
from db_migration_manager import (
DatabaseModel,
primary_key,
unique_field,
indexed_field,
db_field
)
class User(DatabaseModel):
# Primary key with auto-increment
id: int = primary_key(default=None)
# Unique field with length constraint
email: str = unique_field(max_length=255)
# Indexed field
username: str = indexed_field(max_length=50)
# Custom field with multiple constraints
slug: str = db_field(
unique=True,
index=True,
max_length=100
)
# Regular Pydantic field (stored as TEXT/VARCHAR)
bio: Optional[str] = None
# JSON field (stored as JSONB in PostgreSQL, JSON in MySQL, TEXT in SQLite)
metadata: dict = Field(default_factory=dict)
# Enum field (stored as VARCHAR)
status: UserStatus = Field(default=UserStatus.ACTIVE)
Supported Field Annotations
primary_key(**kwargs)- Creates a primary key field with auto-incrementunique_field(**kwargs)- Creates a unique fieldindexed_field(**kwargs)- Creates an indexed fielddb_field(**kwargs)- Custom field with database-specific options:primary_key: bool- Primary key constraintunique: bool- Unique constraintindex: bool- Create indexunique_index: bool- Create unique indexauto_increment: bool- Auto-increment for integersmax_length: int- Maximum length for strings
Type Mapping
| Python Type | PostgreSQL | MySQL | SQLite |
|---|---|---|---|
str |
VARCHAR(255) | VARCHAR(255) | TEXT |
int |
INTEGER | INT | INTEGER |
float |
DOUBLE PRECISION | DOUBLE | REAL |
bool |
BOOLEAN | TINYINT(1) | INTEGER |
datetime |
TIMESTAMP | DATETIME | TIMESTAMP |
date |
DATE | DATE | DATE |
Decimal |
DECIMAL | DECIMAL | DECIMAL |
list/dict |
JSONB | JSON | TEXT |
Enum |
VARCHAR(50) | VARCHAR(50) | TEXT |
Contributing
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
License
This project is licensed under the MIT License - see the LICENSE file for details.
Support
Related Projects
- Alembic - SQLAlchemy-based migrations
- Django Migrations - Django's migration system
- Flyway - Database migration tool for Java
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file db_migration_manager-2.0.0.tar.gz.
File metadata
- Download URL: db_migration_manager-2.0.0.tar.gz
- Upload date:
- Size: 27.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.10.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0056a73f3bc868cc50ed5acb42c6f10269a66953fa1451f3efcf071299752820
|
|
| MD5 |
5fd7d4d64364ba6ae01fe62f66af46e0
|
|
| BLAKE2b-256 |
bb2945516c0c333be535ecc0963d3e1d8ab3f9e18bc3199c5eb31671fd6fa176
|
File details
Details for the file db_migration_manager-2.0.0-py3-none-any.whl.
File metadata
- Download URL: db_migration_manager-2.0.0-py3-none-any.whl
- Upload date:
- Size: 31.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.10.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4b84ab76105cb1db5b62b4422ff750e925c189a0e35fd7a82429838ad100242b
|
|
| MD5 |
00ef9f868e2c38131a6f19545f2add5a
|
|
| BLAKE2b-256 |
75b1a3b238ec73c35aeb9e8fb5e37216a70ae52c4f3b2dda86c3236aafd5f8b3
|