{ "info": { "author": "Daniel Holth", "author_email": "dholth@fastmail.fm", "bugtrack_url": null, "classifiers": [ "Intended Audience :: Developers", "License :: OSI Approved :: BSD License", "Programming Language :: Python", "Topic :: Database :: Front-Ends" ], "description": "stucco_evolution\n================\n\nDemo\n----\n\nTypical use::\n\n import sqlalchemy\n import stucco_evolution\n\n engine = sqlalchemy.create_engine(...)\n\n with engine.begin() as connection:\n stucco_evolution.initialize(connection)\n stucco_evolution.create_or_upgrade_packages(connection, 'mypackage')\n\nstucco_evolution creates or upgrades the database schema for itself,\n'mypackage', and the dependencies of 'mypackage', in a transaction, in \nthe correct, topologically-sorted order.\n\nSummary\n-------\n\nstucco_evolution's distinguishing feature is that it can be used to\npublish related database schemas as separate packages instead of having\nto manage them monolithically. By keeping track of dependencies between\nschemas, tables for e.g. User / Group models are automatically created\nor upgraded before the more application-specific tables. The intent is\nto enable greater reuse of database code.\n\nstucco_evolution extends repoze.evolution for SQLAlchemy. It provides a\nsimple way to implement schema migrations within a single package as a\ncollection of numbered Python scripts, and it provides a way for packages\nto depend on each other's schema as a directed acyclic graph, creating\nand upgrading each schema's tables in topological dependency order.\n\nstucco_evolution passes a SQLAlchemy connection to a package of numbered\nscripts in order, remembers the versions of installed schema, and sorts\na collection of `evolve` packages by dependency order. It delegates\nwriting the actual `ALTER TABLE` statements to another library or your\nbrain. It delegates schema downgrades to a proper database backup.\n\nstucco_evolution was written as support code for a web application, then\nextracted from that code, extended, and published. It is now intendend to\nmanage the database schema for itself and other stucco_* packages to be\nreleased someday. I hope you will find it useful for your own packages,\ntoo. However, this software is provided \"as is\" and without any express or\nimplied warranties, including, without limitation, the implied warranties\nof merchantibility and fitness for a particular purpose.\n\nUsage\n-----\n\nIf your package is called `mypackage`, you can add an evolution module\nwhich must be called `evolve`. This module will contain scripts to\ncreate and migrate your schema from one version to the next::\n\n\tcd mypackage\n\tmkdir evolve\n\ttouch evolve/__init__.py\n\n`evolve/__init__.py` must contain three constants::\n\n\tNAME = 'mypackage' # stucco_evolution imports 'mypackage' + '.evolve'\n\tVERSION = 0\n\tDEPENDS = []\n\n`evolve/create.py` should always create the most current `VERSION` of your schema. It should be idempotent::\n\n\tdef create(connection):\n\t import mypackage.models\n\t mypackage.models.Base.metadata.create_all(connection)\n\n(If you have Paste Script installed you can type `paster create\n-t stucco_evolution [mypackage]` to create an evolution module in\n[mypackage]/evolve. Since Paste Script's package name substitution is\nnot perfect, check mypackage/evolve/__init__.py to make sure NAME +\n'.evolve' can be imported.)\n\nNow you are ready to create your versioned schema::\n\n import sqlalchemy\n import stucco_evolution\n\n engine = sqlalchemy.create_engine(...)\n\n with engine.begin() as connection: # engine.begin() since SQLAlchemy 0.7.6\n stucco_evolution.initialize(connection)\n stucco_evolution.create_or_upgrade_packages(connection, 'mypackage')\n\nIn this pattern, stucco_evolution tries to create the schema for\n`mypackage` and all its dependencies, in topological order, if they\nare not currently tracked in the stucco_evolution table. `create.py`\nwill only ever be called once for a particular package, so the evolution\nscripts must be responsible for creating new tables added in a particular\n`VERSION` of the schema.\n\nEventually `mypackage` will need a new `VERSION`. To do this, you must\nincrement `VERSION` to N and add `evolve/evolveN.py` to the evolution\nmodule.\n\n`evolve/__init__.py`::\n\n\tNAME = 'mypackage'\n\tVERSION = 1\n\tDEPENDS = []\n\n`evolve/evolve1.py`::\n\n\tdef evolve(connection):\n\t connection.execute(\"CREATE TABLE foo (bar INTEGER)\")\n\t connection.execute(\"ALTER TABLE baz ADD COLUMN quux INTEGER\")\n\nThe next time you call `create_or_upgrade(...)`, stucco_evolution will\nnotice `mymodule` is already tracked in the stucco_evolution table but\nits database version less than `mymodule.evolve.VERSION`. To rectify,\nstucco_evolution calls each evolveN.py greater than the database version\nin order to bring the database up to date.\n\nIn case of dependencies, `stucco_evolution` will try to create or bring\neach dependency package fully up-to-date before trying to upgrade its\ndependent packages. Dependency support is an experimental feature.\n\nOmitted features\n----------------\n\nThere is no provision for downgrade scripts. I used to write them myself\nbut I never used them. Instead, back up your database and test against\na temporary testing database.\n\nThere is no DDL abstraction library. Feel free to use any one you like, or\njust write the ALTER TABLE statements yourself.\n\nRobust upgrade scripts\n----------------------\n\nIf you are arrogant enough to release your package as a dependency to another\npackage or if it will be widely installed, you need to make sure your upgrade\nscripts are robust. The most important rule:\n\n* New code must never change the output of old evolution scripts.\n\nThe simplest way to do this is to issue all DDL as text and never import\nyour package in evolve scripts or call SQLAlchemy's create_all()\nexcept in the create script. You could also try copying and pasting\nyour model into each evolve script, as suggested by sqlalchemy-migrate,\nso SQLAlchemy can generate the DDL. You could keep backups of each version\nof the schema and write tests that restore each backup and upgrade to the\nlatest version to make sure this remains possible for all prior versions.\n\n\n\n0.4\n---\n- create_many() checks whether schema has been installed\n\n0.35\n----\n- fix manifest to properly include paster template\n- remove unnecessary argparse dependency\n\n0.34\n----\n- add `paster create -t stucco_evolution mypackage` to create an evolution\n module in `mypackage/evolve/...`\n\n0.33\n----\n- Backwards-incompatible change. A SQLAlchemy connection is now required\n everywhere a session was previously expected.\n This is necessary for transactional DDL (the ability to roll back a\n migration that throws an exception.)\n\n0.12\n----\n- Add create_or_upgrade_packages(session, 'packagename') convenience function\n\n0.11\n----\n- Backwards-incompatible API changes\n- Improve documentation\n- Detect circular dependencies between evolution modules\n- Regain 100% statement coverage (however, unit tests depend on several\n unreleased packages)\n\n0.10\n----\n- Add multi-package schema evolution support with DAG-ordered dependencies\n\n0.9\n---\n\n- Rename to stucco_evolution\n- stucco_evolution's own upgrade() will now deletage all\n stucco_evolution.Base.metadata.create_all(session) to the evolveN.py\n scripts. This avoids 'DROP TABLE' statements when an upgrade includes\n table renames.\n\n0.8998\n------\n\n- Improved packageability (MANIFEST.in specified)\n- SQLAlchemyEvolutionManager no longer calls session.commit(); this is\n your responsibility after the migration has completed.\n\n0.8\n---\n\n- 100% statement coverage\n\n0.0\n---\n\n- Initial version\n\n\n", "description_content_type": "", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "http://bitbucket.org/dholth/stucco_evolution", "keywords": "sqlalchemy stucco", "license": "BSD", "maintainer": "", "maintainer_email": "", "name": "stucco-evolution", "package_url": "https://pypi.org/project/stucco-evolution/", "platform": "", "project_url": "https://pypi.org/project/stucco-evolution/", "project_urls": { "Homepage": "http://bitbucket.org/dholth/stucco_evolution" }, "release_url": "https://pypi.org/project/stucco-evolution/0.50.0/", "requires_dist": [ "SQLAlchemy", "repoze.evolution", "six" ], "requires_python": "", "summary": "Moderately simple schema upgrades for SQLAlchemy.", "version": "0.50.0" }, "last_serial": 5911997, "releases": { "0.11": [ { "comment_text": "", "digests": { "md5": "429f155e3a2e89d2d0978f734be1c13c", "sha256": "97f0b49692438235267d6eb5a6be6892a76f7604958d68076e2ed4d9f9bc78de" }, "downloads": -1, "filename": "stucco_evolution-0.11.tar.gz", "has_sig": false, "md5_digest": "429f155e3a2e89d2d0978f734be1c13c", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 7542, "upload_time": "2011-01-12T06:36:43", "url": "https://files.pythonhosted.org/packages/6a/d9/2ece0af644d8fbcbd015bc93f7a650545080a1b4c3809165f825cb8714aa/stucco_evolution-0.11.tar.gz" } ], "0.12": [ { "comment_text": "", "digests": { "md5": "6fbbd687560e60ef2345d0188fb1486f", "sha256": "b8f135cb6e81cb6aee4e4536a04865a299575a82068ecccd134cff877b58e44b" }, "downloads": -1, "filename": "stucco_evolution-0.12.tar.gz", "has_sig": false, "md5_digest": "6fbbd687560e60ef2345d0188fb1486f", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 7642, "upload_time": "2011-01-16T00:47:10", "url": "https://files.pythonhosted.org/packages/27/5b/eab7adba2235fec6e6aac30348ad946b56eace94a73f257d1dc6f6f72e03/stucco_evolution-0.12.tar.gz" } ], "0.33": [ { "comment_text": "", "digests": { "md5": "6426102a001b41ab99a569477bac9bc1", "sha256": "ee5cba9a0910d9f78d1f90975d543d6d17ee7751d4dcbcc313fa5ed86221137b" }, "downloads": -1, "filename": "stucco_evolution-0.33.tar.gz", "has_sig": false, "md5_digest": "6426102a001b41ab99a569477bac9bc1", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 10533, "upload_time": "2011-02-22T22:47:52", "url": "https://files.pythonhosted.org/packages/8f/9f/d58e2e30da8eef6a93f20fb28c3b928dc7f873909bfa69827322a4775861/stucco_evolution-0.33.tar.gz" } ], "0.34": [ { "comment_text": "", "digests": { "md5": "fa26427688a3703d29266850bf749070", "sha256": "c8718e7b2ecc3a5259732049d10f6e8afd18c71e3214701520d161e09b1b8eb1" }, "downloads": -1, "filename": "stucco_evolution-0.34.tar.gz", "has_sig": false, "md5_digest": "fa26427688a3703d29266850bf749070", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 8766, "upload_time": "2011-03-12T20:35:53", "url": "https://files.pythonhosted.org/packages/a2/31/683227c4cd7a4d7183c46e52395db5844bd666aafd7abf079e185d31b5b4/stucco_evolution-0.34.tar.gz" } ], "0.35": [ { "comment_text": "", "digests": { "md5": "e5a46d9234d9f963ef848e6ab28e4472", "sha256": "a70cc5282bc1e314e45b2ce6b7ba7af83b63e6c0c5f7ef96ef06ee5e250270dc" }, "downloads": -1, "filename": "stucco_evolution-0.35.tar.gz", "has_sig": false, "md5_digest": "e5a46d9234d9f963ef848e6ab28e4472", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 9061, "upload_time": "2011-03-15T18:53:18", "url": "https://files.pythonhosted.org/packages/72/24/2cacde9d1b470b708ad40870a24eadf73d27f6b071868c8523194093264a/stucco_evolution-0.35.tar.gz" } ], "0.4": [ { "comment_text": "", "digests": { "md5": "b763ba6bbc1f1ca7abbc37d0ac86e6b0", "sha256": "aaf2a38d96329741a7e3ccd95a9220b24d83879ff43fbfae5fc4480653db2bb8" }, "downloads": -1, "filename": "stucco_evolution-0.4.tar.gz", "has_sig": false, "md5_digest": "b763ba6bbc1f1ca7abbc37d0ac86e6b0", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 8981, "upload_time": "2012-04-18T19:10:28", "url": "https://files.pythonhosted.org/packages/62/8a/d0607ff32e25fe44f50064365eb145fb316bc11c5d1e2b1f753c67b124a5/stucco_evolution-0.4.tar.gz" } ], "0.42.0": [ { "comment_text": "", "digests": { "md5": "997a869ab854d3e2021bfd329c2e7700", "sha256": "ff9a44cf1d39dd383350467106fb26bef23f6fd085d2ffe4cf00ad8d2cbafe47" }, "downloads": -1, "filename": "stucco_evolution-0.42.0.tar.gz", "has_sig": false, "md5_digest": "997a869ab854d3e2021bfd329c2e7700", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 9203, "upload_time": "2013-06-18T13:12:01", "url": "https://files.pythonhosted.org/packages/f3/7a/b4c53d45f7337b7e21325cfe8e94f19ae7aa9fb86db04b2cffc97beea71f/stucco_evolution-0.42.0.tar.gz" } ], "0.5.0": [ { "comment_text": "", "digests": { "md5": "a5ddfea546d42e7510ee28468dc07f84", "sha256": "25c6d563b7f3c93628c288b2c58e3617d1c9c70aa19b78d5e1ceeb852636ce25" }, "downloads": -1, "filename": "stucco_evolution-0.5.0-py3-none-any.whl", "has_sig": false, "md5_digest": "a5ddfea546d42e7510ee28468dc07f84", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 11313, "upload_time": "2019-10-01T01:55:56", "url": "https://files.pythonhosted.org/packages/3c/43/4085e3a1fe573511d5c1c0a7a640801e96fc7e7a601c5f573801ad432e8b/stucco_evolution-0.5.0-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "cbe07a78cc183abb248d2c7b2188e75c", "sha256": "a878a980535da51706b29fe01e2444de961c45149111029e0a9be9a502c07926" }, "downloads": -1, "filename": "stucco_evolution-0.5.0.tar.gz", "has_sig": false, "md5_digest": "cbe07a78cc183abb248d2c7b2188e75c", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 12030, "upload_time": "2019-10-01T01:55:58", "url": "https://files.pythonhosted.org/packages/8a/69/59152d42bfa37230fe321898dce22020b3888acc4ca0165cb255fef6998f/stucco_evolution-0.5.0.tar.gz" } ], "0.50.0": [ { "comment_text": "", "digests": { "md5": "153e97852d5baf1feac376437feba653", "sha256": "57574850e7a807ef62e132b060001d1c56c1608da60708cd94f4b1ca3c8b964b" }, "downloads": -1, "filename": "stucco_evolution-0.50.0-py3-none-any.whl", "has_sig": false, "md5_digest": "153e97852d5baf1feac376437feba653", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 11326, "upload_time": "2019-10-01T12:26:05", "url": "https://files.pythonhosted.org/packages/35/f4/030029aab6d6428a761efab2c0676d2f1d99d44beaefd2af8462112fe930/stucco_evolution-0.50.0-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "46d3bf8274cc76b0c3345c357cbab9e8", "sha256": "414478148df3b76bdb7f7e8439d74792219ea805c8e95ac4947fa375a3bc99d0" }, "downloads": -1, "filename": "stucco_evolution-0.50.0.tar.gz", "has_sig": false, "md5_digest": "46d3bf8274cc76b0c3345c357cbab9e8", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 12044, "upload_time": "2019-10-01T12:26:06", "url": "https://files.pythonhosted.org/packages/95/8d/73543e88bb81b1a9b5d3a8579b97d872ea084177e3ff6892fc70660f48d6/stucco_evolution-0.50.0.tar.gz" } ], "0.9": [ { "comment_text": "", "digests": { "md5": "42d6df9864b3ecf3cee7cf4f97cf7fa3", "sha256": "164973f7d7f2d139431ce348b354df63a33a5f20f0bdb1ee050c276f4c66b8c6" }, "downloads": -1, "filename": "stucco_evolution-0.9.tar.gz", "has_sig": false, "md5_digest": "42d6df9864b3ecf3cee7cf4f97cf7fa3", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 3616, "upload_time": "2010-12-08T21:19:18", "url": "https://files.pythonhosted.org/packages/ef/e4/2f7e11153d437ef130e2a3fb72e11f9dfd5e59b79a6aa8bf4202ab0f3034/stucco_evolution-0.9.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "153e97852d5baf1feac376437feba653", "sha256": "57574850e7a807ef62e132b060001d1c56c1608da60708cd94f4b1ca3c8b964b" }, "downloads": -1, "filename": "stucco_evolution-0.50.0-py3-none-any.whl", "has_sig": false, "md5_digest": "153e97852d5baf1feac376437feba653", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 11326, "upload_time": "2019-10-01T12:26:05", "url": "https://files.pythonhosted.org/packages/35/f4/030029aab6d6428a761efab2c0676d2f1d99d44beaefd2af8462112fe930/stucco_evolution-0.50.0-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "46d3bf8274cc76b0c3345c357cbab9e8", "sha256": "414478148df3b76bdb7f7e8439d74792219ea805c8e95ac4947fa375a3bc99d0" }, "downloads": -1, "filename": "stucco_evolution-0.50.0.tar.gz", "has_sig": false, "md5_digest": "46d3bf8274cc76b0c3345c357cbab9e8", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 12044, "upload_time": "2019-10-01T12:26:06", "url": "https://files.pythonhosted.org/packages/95/8d/73543e88bb81b1a9b5d3a8579b97d872ea084177e3ff6892fc70660f48d6/stucco_evolution-0.50.0.tar.gz" } ] }