{ "info": { "author": "Lieturd O\u00dc", "author_email": "janne@lieturd.com", "bugtrack_url": null, "classifiers": [ "License :: OSI Approved :: BSD License", "Programming Language :: Python :: 2", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7" ], "description": ".. image:: https://travis-ci.org/lieturd/migrate-anything.svg?branch=master\n :target: https://travis-ci.org/lieturd/migrate-anything\n\n.. image:: https://img.shields.io/badge/code%20style-black-000000.svg\n :target: https://github.com/psf/black\n\n.. image:: https://codecov.io/gh/Lieturd/migrate-anything/branch/master/graph/badge.svg\n :target: https://codecov.io/gh/Lieturd/migrate-anything\n\n.. image:: https://sonarcloud.io/api/project_badges/measure?project=Lieturd_migrate-anything&metric=alert_status\n :target: https://sonarcloud.io/dashboard?id=Lieturd_migrate-anything\n\nMigrate anything - database (etc.) migration utility, especially for Python projects.\n\n\nWhat is this?\n=============\n\nIt'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.\n\nThis project is an attempt to change that.\n\n\nUsage examples\n==============\n\nFirstly you'll need this package in your project. Pick one of these:\n\n.. code-block:: python\n\n pip install -U migrate-anything\n poetry add migrate-anything\n pipenv install migrate-anything\n\nSimply put, create a Python package, don't be too clever and call it e.g. ``migrations``. Then put files in that package:\n\n.. code-block:: python\n\n # migrations/__init__.py\n from migrate_anything import configure, CSVStorage\n\n configure(storage=CSVStorage(\"migration_status.csv\"))\n\n.. code-block:: python\n\n # migrations/01-initialize-db.py\n # Please note that this is built for a completely hypothetical DB layer\n from my_db import get_db\n\n DB = get_db()\n\n def up():\n DB.create_table(\"example\")\n\n def down():\n DB.delete_table(\"example\")\n\nThis 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 the command\n\n.. code-block:: shell\n\n migrate-anything migrations\n\nNow 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:\n\n.. code-block:: python\n\n # __init__.py\n from migrate_anything import configure, MongoDBStorage\n import pymongo\n\n db = pymongo.MongoClient().my_db\n\n configure(storage=MongoDBStorage(db.migrations))\n\n.. code-block:: python\n\n # 01-initialize-db.py\n from pymongo import MongoClient\n\n client = MongoClient()\n db = client.my_db\n\n def up():\n db.posts.insert_one({\n \"id\": \"post-1\",\n \"title\": \"We're live!\",\n \"content\": \"This is our first post, yay.\"\n })\n db.posts.create_index(\"id\")\n\n def down():\n db.posts.drop()\n\nThis would configure storage to a ``my_db.migrations`` MongoDB collection.\n\nFuture ideas include support for other DB engines (feel free to contribute),\nand Kubernetes ConfigMap. Annoyingly storage to Kubernetes from inside a pod\nand in code is not quite as simple as just running ``kubectl``.\n\nOh 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 `_.\n\nAlternatively you can just write your own - it's easy.\n\n.. code-block:: python\n\n # __init__.py\n from migrate_anything import configure\n\n\n class CustomStorage(object):\n def __init__(self, file):\n self.file = file\n\n def save_migration(self, name, code):\n with open(self.file, \"a\", encoding=\"utf-8\") as file:\n file.write(\"{},{}\\n\".format(name, code))\n\n def list_migrations(self):\n try:\n with open(self.file, encoding=\"utf-8\") as file:\n return [\n line.split(\",\")\n for line in file.readlines()\n if line.strip() # Skip empty lines\n ]\n except FileNotFoundError:\n return []\n\n def remove_migration(self, name):\n migrations = [\n migration for migration in self.list_migrations() if migration[0] != name\n ]\n\n with open(self.file, \"w\", encoding=\"utf-8\") as file:\n for row in migrations:\n file.write(\"{},{}\\n\".format(*row))\n\n\n configure(storage=CustomStorage(\"test.txt\"))\n\nYou can also check out the `examples `_.", "description_content_type": "text/x-rst", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/Lieturd/migrate-anything", "keywords": "migrate database db release", "license": "", "maintainer": "", "maintainer_email": "", "name": "migrate-anything", "package_url": "https://pypi.org/project/migrate-anything/", "platform": "", "project_url": "https://pypi.org/project/migrate-anything/", "project_urls": { "Bug Reports": "https://github.com/Lieturd/migrate-anything/issues", "Homepage": "https://github.com/Lieturd/migrate-anything", "Source": "https://github.com/Lieturd/migrate-anything/" }, "release_url": "https://pypi.org/project/migrate-anything/0.1.5/", "requires_dist": null, "requires_python": ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, <4", "summary": "Helps manage migrations for databases and anything else", "version": "0.1.5" }, "last_serial": 5967234, "releases": { "0.1.2": [ { "comment_text": "", "digests": { "md5": "e66dd31f0cf096333969affc6613ef43", "sha256": "4b6a54dbb725b42258e8f3bb21a3f49b11e3d25c587acfbd1c4f2c4f8f1340c8" }, "downloads": -1, "filename": "migrate_anything-0.1.2-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "e66dd31f0cf096333969affc6613ef43", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*, <4", "size": 7886, "upload_time": "2019-10-12T23:51:08", "url": "https://files.pythonhosted.org/packages/0e/3a/bc270834f3b12367c88fd56726b487d69edbcbb6e09699c1c81829017da1/migrate_anything-0.1.2-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "5f03d806c1207304c8dd1a8c549dc2ca", "sha256": "30fe733f9dd1cf718d4814279ad71d593601399c5be87912b2f7ad62db294953" }, "downloads": -1, "filename": "migrate-anything-0.1.2.tar.gz", "has_sig": false, "md5_digest": "5f03d806c1207304c8dd1a8c549dc2ca", "packagetype": "sdist", "python_version": "source", "requires_python": ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*, <4", "size": 5770, "upload_time": "2019-10-12T23:51:10", "url": "https://files.pythonhosted.org/packages/0d/45/8794d8703684b6d2ae915b6c7a13a0904356f772a2fc3ee6836448a9b795/migrate-anything-0.1.2.tar.gz" } ], "0.1.3": [ { "comment_text": "", "digests": { "md5": "25050c3764fbc4d8cb3fbd05de4f3710", "sha256": "03e27666b2587199f4351aeaad90e7a3a86db2cc50a8fe05b31cf09018b5990f" }, "downloads": -1, "filename": "migrate_anything-0.1.3-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "25050c3764fbc4d8cb3fbd05de4f3710", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, <4", "size": 7884, "upload_time": "2019-10-13T00:02:30", "url": "https://files.pythonhosted.org/packages/fc/6e/63e1ed85a353dc7a077bdfab9a6e241b80a346d13a3acf97b23b879fdb08/migrate_anything-0.1.3-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "354d0a20836ccf6f62d8a7a243f71907", "sha256": "28393361d3d040e6913a6d9518b8af53195404ff4a0f04b1e22352a54daf37f4" }, "downloads": -1, "filename": "migrate-anything-0.1.3.tar.gz", "has_sig": false, "md5_digest": "354d0a20836ccf6f62d8a7a243f71907", "packagetype": "sdist", "python_version": "source", "requires_python": ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, <4", "size": 5765, "upload_time": "2019-10-13T00:02:32", "url": "https://files.pythonhosted.org/packages/15/33/6cbec6ae87ce3d3adc6c04cc07990c9b568cc2e25ee85baa61461d1c7859/migrate-anything-0.1.3.tar.gz" } ], "0.1.4": [ { "comment_text": "", "digests": { "md5": "0736288f41cd9809bd26d549e8827e6d", "sha256": "2189248a602255ee5131b32ac2a27fcbf7884374f313ca0141a6163d37853e39" }, "downloads": -1, "filename": "migrate_anything-0.1.4-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "0736288f41cd9809bd26d549e8827e6d", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, <4", "size": 8263, "upload_time": "2019-10-13T11:35:38", "url": "https://files.pythonhosted.org/packages/27/f2/8db10fb2289bc53593d2780e66a0d5b284b39a76fcd788d765d85aebdfb4/migrate_anything-0.1.4-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "462b36c7456fe6f125f1347e27b9eeb2", "sha256": "9052ceadec7b3097eb815c4d539264830f4c53b3c5c007ba98cdd9e80b16e52b" }, "downloads": -1, "filename": "migrate-anything-0.1.4.tar.gz", "has_sig": false, "md5_digest": "462b36c7456fe6f125f1347e27b9eeb2", "packagetype": "sdist", "python_version": "source", "requires_python": ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, <4", "size": 6260, "upload_time": "2019-10-13T11:34:20", "url": "https://files.pythonhosted.org/packages/a8/b8/e8138357e08662f073c035e1ea97b8d15b0ac7ccb278e187eb83795cbeb0/migrate-anything-0.1.4.tar.gz" } ], "0.1.5": [ { "comment_text": "", "digests": { "md5": "1c208158814aba80f12cbfbb3c82d47f", "sha256": "0631c088c66a076984d152ff470aa8b0ad0f8cff1f80f3072126867d0cbbc0a0" }, "downloads": -1, "filename": "migrate-anything-0.1.5.tar.gz", "has_sig": false, "md5_digest": "1c208158814aba80f12cbfbb3c82d47f", "packagetype": "sdist", "python_version": "source", "requires_python": ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, <4", "size": 6276, "upload_time": "2019-10-13T12:14:30", "url": "https://files.pythonhosted.org/packages/42/7b/0ce52e8ec876027a3e37ce47853d0cf0239bae411edf9dbc1533e04ac4fa/migrate-anything-0.1.5.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "1c208158814aba80f12cbfbb3c82d47f", "sha256": "0631c088c66a076984d152ff470aa8b0ad0f8cff1f80f3072126867d0cbbc0a0" }, "downloads": -1, "filename": "migrate-anything-0.1.5.tar.gz", "has_sig": false, "md5_digest": "1c208158814aba80f12cbfbb3c82d47f", "packagetype": "sdist", "python_version": "source", "requires_python": ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, <4", "size": 6276, "upload_time": "2019-10-13T12:14:30", "url": "https://files.pythonhosted.org/packages/42/7b/0ce52e8ec876027a3e37ce47853d0cf0239bae411edf9dbc1533e04ac4fa/migrate-anything-0.1.5.tar.gz" } ] }