{ "info": { "author": "Andrey Petrov", "author_email": "andrey.petrov@shazow.net", "bugtrack_url": null, "classifiers": [], "description": "===============================================\nSQLAlchemyGrate SQLAlcheMygrate SQLAlcheMyGrate\n===============================================\n\nThis is my silly (yet effective) migration framework built on `SQLAlchemy `_ \u2014 the best database abstraction library in the universe. Grate doesn't do fancy things like track schema versions and do step-through upgrade/downgrade paths or testing. Buuut, you can create a wrapper around it to do all these things using the ``upgrade`` command.\n\nOne thing grate does well out of the box is a stupid row-by-row re-insert from one SQLAlchemy target engine to another. This means you can make changes to your SQLAlchemy schema as you please, then to port your data you create another database and do a row-by-row re-insert from the old dataset into the new. You can even provide a conversion function that will transform the data when necessary.\n\n**Warning**: *Consider this beta quality. There is a lack of error checking so you may get rogue exceptions raised. More features and helpers are being added.*\n\nUsage\n=====\n\n::\n\n Usage: grate COMMAND [ARGS ...]\n\n Really silly schema migration framework, built for SQLAlchemy.\n\n Commands:\n migrate ENGINE_FROM ENGINE_TO\n Migrate schema or data from one engine to another.\n\n upgrade ENGINE UPGRADE_FN\n Perform in-place upgrade of a schema in an engine.\n\n Examples:\n grate migrate \"mysql://foo:bar@localhost/baz\" \"sqlite:///:memory:\" \\\n --metadata model.meta:metadata --verbose\n\n grate upgrade \"mysql://foo:bar@localhost/baz\" migration.001_change_fancy_column:upgrade\n\n Hint: The upgrade command can also be used to downgrade, just point it\n to the relevant downgrade function. For extra awesomeness, use schema-altering\n DDLs provided by sqlalchemy-migrate.\n\n\n Options:\n -h, --help show this help message and exit\n -v, --verbose Enable verbose output. Use twice to enable debug\n output.\n --show-sql Echo SQLAlchemy queries.\n\n migrate:\n --only-tables=TABLES\n Only perform migration on the given tables. (comma-\n separated table names)\n --skip-tables=TABLES\n Skip migration on the given tables. (comma-separated\n table names)\n --limit=LIMIT Number to select per insert loop. (default: 100000)\n --metadata=METADATA\n MetaData object bound to the target schema definition.\n Example: model.metadata:MetaData\n --convert=FN (Optional) Convert function to run data through.\n Example: migration.v1:convert\n\n\nFunction examples\n=================\n\nconvert\n-------\n\nWhen migrating, you can provide a conversion function to funnel data through. Here's what one could look like::\n\n # migration/v1.py:\n\n def convert(table, row):\n \"\"\"\n :param table: SQLAlchemy table schema object.\n :param row: Current row from the given table (immutable, must make a copy to change).\n\n Returns a dict with column:value mappings.\n \"\"\"\n if table.name == 'user':\n row = dict(row)\n row['email'] = row['email'].lower()\n elif table.name == 'job':\n row = dict(row)\n del row['useless_column']\n\n return row\n\nThen we would use this function with ``--convert=migration.v1:convert``. There's pretty obvious performance detriment from using this feature, namely having to run each row through a function with its own logic, but with small datasets it's not too bad and too convenient to ignore.\n\n\nupgrade\n--------\n\nWhen performing an upgrade command, you can do in-place changes without a full re-insert. This is a more realistic alternative to larger datasets or small schema changes.\n\n::\n\n # migration/001_add_fancy_column.py:\n\n from sqlalchemy import *\n from migrate import * # sqlalchemy-migrate lets us do dialect-agnostic schema changes\n\n # sqlalchemygrate also provides some helpers just in case\n from grate.migrations import table_migrate\n\n def upgrade(metadata):\n \"\"\"\n :param metadata: SQLAlchemy MetaData bound to an engine and autoreflected.\n \"\"\"\n fancy_table = metadata.tables['fancy_table']\n\n # Create column using sqlalchemy-migrate\n col = Column('fancy_column', types.Integer)\n col.create(fancy_table)\n\n ## Or run some arbitrary SQL\n # metadata.bind.execute(...)\n\n ## Need to do a row-by-row re-insert? Use the table_migrate helper\n ## We do a migration from one engine to the same engine, but between two different tables this time.\n # table_migrate(metadata.bind, metadata.bind, table, renamed_table, convert_fn=None, limit=100000)\n\n def downgrade(metadata):\n fancy_table = metadata.tables['fancy_table']\n fancy_table.c.fancy_column.drop()\n\n\nThis feature becomes *even more powerful* if you combine it with `sqlalchemy-migrate `_. This way you can use dialect-agnostic SQLAlchemy DDLs to generate your schema changes, but without having to depend on sqlalchemy-migrate's revision tracking and other needless complexities which drove me to write this.\n\nAnd now we can upgrade and downgrade our schema, for example::\n\n grate upgrade \"sqlite:///development.db\" migration.001_change_fancy_column:upgrade --show-sql\n grate upgrade \"sqlite:///development.db\" migration.001_change_fancy_column:downgrade --shoq-sql\n\nMaybe this should be called something other than ``upgrade``? Perhaps ``grade``? Anyways...\n\n\nPerformance Notes\n=================\n\nRow-by-row re-insert (migrate)\n------------------------------\n\nThousands of rows takes seconds, millions of rows takes minutes. The details are dependent on the schema, server, and specific numbers.\n\nIn-place schema changes (upgrade)\n---------------------------------\n\nIf you're not doing a full re-insert, this is about as efficient as you can get with any other schema migration tool. Typically on the order of seconds.\n\n\n\n==============================\nQuestions? Want to contribute?\n==============================\n\n* You can email me at andrey.petrov@shazow.net\n* Tweet me at `@shazow `_\n* `Open an issue `_ or make a fork :D\n\n\n====\nTODO\n====\n\n* More concrete examples (fill out the code TODOs)\n* More helpers for common migration operations\n* Build a wrapper around grate to handle revision tracking and step-through upgrade procedures like most mainstream migration frameworks.\n\n\n=================\nISN'T THIS GRATE?\n=================", "description_content_type": null, "docs_url": null, "download_url": null, "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "http://github.com/shazow/sqlalchemygrate", "keywords": null, "license": "MIT", "maintainer": null, "maintainer_email": null, "name": "sqlalchemygrate", "package_url": "https://pypi.org/project/sqlalchemygrate/", "platform": "UNKNOWN", "project_url": "https://pypi.org/project/sqlalchemygrate/", "project_urls": { "Homepage": "http://github.com/shazow/sqlalchemygrate" }, "release_url": "https://pypi.org/project/sqlalchemygrate/0.3/", "requires_dist": null, "requires_python": null, "summary": "Silly (but effective) database schema and data migration framework using SQLAlchemy.", "version": "0.3" }, "last_serial": 1614990, "releases": { "0.1": [ { "comment_text": "", "digests": { "md5": "8f2bf5c9a702be09e8406db07591247d", "sha256": "fec82c1f98f774c7c1e9cf2016d6035dd0ccd071a3bd3925e04bd0a0fd05badc" }, "downloads": -1, "filename": "sqlalchemygrate-0.1.tar.gz", "has_sig": false, "md5_digest": "8f2bf5c9a702be09e8406db07591247d", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 5700, "upload_time": "2010-10-14T02:44:53", "url": "https://files.pythonhosted.org/packages/3b/7f/ea95c7a1f1f2af559353839836cd7ed9f52c33f2cae7d26bbaa41cda8ad4/sqlalchemygrate-0.1.tar.gz" } ], "0.3": [ { "comment_text": "", "digests": { "md5": "d10c1866844bca0384e1d8baf6ad199b", "sha256": "b5092bb76ffbca0dfaead18358e782edf417eb48d613acd7f579ffbb6754dd0b" }, "downloads": -1, "filename": "sqlalchemygrate-0.3.macosx-10.9-x86_64.tar.gz", "has_sig": false, "md5_digest": "d10c1866844bca0384e1d8baf6ad199b", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 9357, "upload_time": "2015-07-01T14:53:04", "url": "https://files.pythonhosted.org/packages/ca/ce/3a2764837fe34a28534bbcec5d2d399be9115ace217b92890807a2742a6e/sqlalchemygrate-0.3.macosx-10.9-x86_64.tar.gz" }, { "comment_text": "", "digests": { "md5": "bc06bf6ad586475c02ed60b095d1fb96", "sha256": "eaf2630f1df407173ac9b3d26029736f15e26286fd0a14ec1c134c1eb5dc8af5" }, "downloads": -1, "filename": "sqlalchemygrate-0.3.tar.gz", "has_sig": false, "md5_digest": "bc06bf6ad586475c02ed60b095d1fb96", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 7619, "upload_time": "2015-07-01T14:53:08", "url": "https://files.pythonhosted.org/packages/dd/d9/e168d0d9df4ed90f2d95fb8bbd7ff4151a0463d137d56e8859c34d0b3b4c/sqlalchemygrate-0.3.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "d10c1866844bca0384e1d8baf6ad199b", "sha256": "b5092bb76ffbca0dfaead18358e782edf417eb48d613acd7f579ffbb6754dd0b" }, "downloads": -1, "filename": "sqlalchemygrate-0.3.macosx-10.9-x86_64.tar.gz", "has_sig": false, "md5_digest": "d10c1866844bca0384e1d8baf6ad199b", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 9357, "upload_time": "2015-07-01T14:53:04", "url": "https://files.pythonhosted.org/packages/ca/ce/3a2764837fe34a28534bbcec5d2d399be9115ace217b92890807a2742a6e/sqlalchemygrate-0.3.macosx-10.9-x86_64.tar.gz" }, { "comment_text": "", "digests": { "md5": "bc06bf6ad586475c02ed60b095d1fb96", "sha256": "eaf2630f1df407173ac9b3d26029736f15e26286fd0a14ec1c134c1eb5dc8af5" }, "downloads": -1, "filename": "sqlalchemygrate-0.3.tar.gz", "has_sig": false, "md5_digest": "bc06bf6ad586475c02ed60b095d1fb96", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 7619, "upload_time": "2015-07-01T14:53:08", "url": "https://files.pythonhosted.org/packages/dd/d9/e168d0d9df4ed90f2d95fb8bbd7ff4151a0463d137d56e8859c34d0b3b4c/sqlalchemygrate-0.3.tar.gz" } ] }