Helps manage migrations for databases and anything else
Project description
Migrate anything - database (etc.) migration utility, especially for Python projects.
What is this?
It’s kinda annoying how often you run into the question of how to handle migrations in your project, and there hasn’t seem to emerged any good, DB -agnostic, framework-agnostic, and storage-agnostic tool to manage them.
This project is an attempt to change that.
Basically what it does when you run migrate-anything migrations
is:
Find all the files
migrations/*.py
and sort themAny that are not yet registered in the DB will be loaded, their
up()
is executed, and the file’s contents stored in the DBAny files that are missing from the fs but are in the DB will have their code loaded from the DB and their
down()
is executed - in reverse order
License
Licensing is important. This project uses BSD 3-clause license, and adds no other dependencies to your project (it does use a few things during build & testing) - that’s about as simple, safe, and free to use as it gets.
For more information check the LICENSE -file.
Usage examples
Basic usage
Firstly you’ll need this package in your project. Pick one of these:
pip install -U migrate-anything
poetry add migrate-anything
pipenv install migrate-anything
Simply put, create a Python package, don’t be too clever and call it e.g. migrations. Then put files in that package:
# migrations/__init__.py
from migrate_anything import configure, CSVStorage
configure(storage=CSVStorage("migration_status.csv"))
# migrations/01-initialize-db.py
# Please note that this is built for a completely hypothetical DB layer
from my_db import get_db
DB = get_db()
def up():
DB.create_table("example")
def down():
DB.delete_table("example")
This would configure your migrations’ status to be stored in a local file called migration_status.csv and set up your first migration script. If you have a my_db module that works like this you could just run this with a single command:
migrate-anything migrations
poetry run migrate-anything migrations
pipenv run migrate-anything migrations
Now in the real world you might want something more durable and a realistic example, so here’s e.g. what you’d do when using MongoDB:
# __init__.py
from migrate_anything import configure, MongoDBStorage
import pymongo
db = pymongo.MongoClient().my_db
configure(storage=MongoDBStorage(db.migrations))
# 01-initialize-db.py
from pymongo import MongoClient
client = MongoClient()
db = client.my_db
def up():
db.posts.insert_one({
"id": "post-1",
"title": "We're live!",
"content": "This is our first post, yay."
})
db.posts.create_index("id")
def down():
db.posts.drop()
This would configure storage to a my_db.migrations MongoDB collection.
Command line flags
# Revert the last migration using migration code file.
migrate-anything migrations --revert-latest
Custom storage engines
Writing your own custom storage engine is easy.
# __init__.py
from migrate_anything import configure
class CustomStorage(object):
def __init__(self, file):
self.file = file
def save_migration(self, name, code):
with open(self.file, "a", encoding="utf-8") as file:
file.write("{},{}\n".format(name, code))
def list_migrations(self):
try:
with open(self.file, encoding="utf-8") as file:
return [
line.split(",")
for line in file.readlines()
if line.strip() # Skip empty lines
]
except FileNotFoundError:
return []
def remove_migration(self, name):
migrations = [
migration for migration in self.list_migrations() if migration[0] != name
]
with open(self.file, "w", encoding="utf-8") as file:
for row in migrations:
file.write("{},{}\n".format(*row))
configure(storage=CustomStorage("test.txt"))
You can also check out the examples.
Contributing
This project is run on GitHub using the issue tracking and pull requests here. If you want to contribute, feel free to submit issues (incl. feature requests) or PRs here.
You will need pre-commit set up to make contributions.
To set up development tools for this, run:
pre-commit install
virtualenv .venv
.venv/bin/activate
# OR
.venv\Scripts\activate.bat
pip install -r dev-requirements.txt
pip install -e .
And then to run the tests
pytest
When you have improvements to make, commit (and include any cleanup pre-commit might do), push your changes to your own fork, make a PR.
Future ideas
Future ideas include support for other DB engines (feel free to contribute), and Kubernetes ConfigMap. Annoyingly storage to Kubernetes from inside a pod and in code is not quite as simple as just running kubectl.
Oh and your Kubernetes pods will likely require the necessary RBAC rules to manage their ConfigMap. It’s unfortunately kinda complex, but I’m sure you can figure it out e.g. with this guide.
Financial support
This project has been made possible thanks to Cocreators and Lietu. You can help us continue our open source work by supporting us on Buy me a coffee.
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
Built Distribution
Hashes for migrate_anything-0.1.8-py2.py3-none-any.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | f8f938f2c335a28c1c9fc85b66b8002ed69ad30e9fe4e1958ebb961d47bbe7c6 |
|
MD5 | 29d91df49898bb731261e9e97465f0b2 |
|
BLAKE2b-256 | 8b79283a7c895df4e7cb7d18e32232cd98a1e99442c368cb7a080c23826fa367 |