Metadata-Version: 1.1
Name: stucco-evolution
Version: 0.42.0
Summary: Moderately simple schema upgrades for SQLAlchemy.
Home-page: http://bitbucket.org/dholth/stucco_evolution
Author: Daniel Holth
Author-email: dholth@fastmail.fm
License: BSD
Description: stucco_evolution
        ================
        
        Demo
        ----
        
        Typical use::
        
            import sqlalchemy
            import stucco_evolution
        
            engine = sqlalchemy.create_engine(...)
        
            with engine.begin() as connection:
                stucco_evolution.initialize(connection)
                stucco_evolution.create_or_upgrade_packages(connection, 'mypackage')
        
        stucco_evolution creates or upgrades the database schema for itself,
        'mypackage', and the dependencies of 'mypackage', in a transaction, in 
        the correct, topologically-sorted order.
        
        Summary
        -------
        
        stucco_evolution's distinguishing feature is that it can be used to
        publish related database schemas as separate packages instead of having
        to manage them monolithically.  By keeping track of dependencies between
        schemas, tables for e.g. User / Group models are automatically created
        or upgraded before the more application-specific tables.  The intent is
        to enable greater reuse of database code.
        
        stucco_evolution extends repoze.evolution for SQLAlchemy. It provides a
        simple way to implement schema migrations within a single package as a
        collection of numbered Python scripts, and it provides a way for packages
        to depend on each other's schema as a directed acyclic graph, creating
        and upgrading each schema's tables in topological dependency order.
        
        stucco_evolution passes a SQLAlchemy connection to a package of numbered
        scripts in order, remembers the versions of installed schema, and sorts
        a collection of `evolve` packages by dependency order. It delegates
        writing the actual `ALTER TABLE` statements to another library or your
        brain. It delegates schema downgrades to a proper database backup.
        
        stucco_evolution was written as support code for a web application, then
        extracted from that code, extended, and published. It is now intendend to
        manage the database schema for itself and other stucco_* packages to be
        released someday. I hope you will find it useful for your own packages,
        too. However, this software is provided "as is" and without any express or
        implied warranties, including, without limitation, the implied warranties
        of merchantibility and fitness for a particular purpose.
        
        Usage
        -----
        
        If your package is called `mypackage`, you can add an evolution module
        which must be called `evolve`. This module will contain scripts to
        create and migrate your schema from one version to the next::
        
        	cd mypackage
        	mkdir evolve
        	touch evolve/__init__.py
        
        `evolve/__init__.py` must contain three constants::
        
        	NAME = 'mypackage' # stucco_evolution imports 'mypackage' + '.evolve'
        	VERSION = 0
        	DEPENDS = []
        
        `evolve/create.py` should always create the most current `VERSION` of your schema. It should be idempotent::
        
        	def create(connection):
        	    import mypackage.models
        	    mypackage.models.Base.metadata.create_all(connection)
        
        (If you have Paste Script installed you can type `paster create
        -t stucco_evolution [mypackage]` to create an evolution module in
        [mypackage]/evolve. Since Paste Script's package name substitution is
        not perfect, check mypackage/evolve/__init__.py to make sure NAME +
        '.evolve' can be imported.)
        
        Now you are ready to create your versioned schema::
        
            import sqlalchemy
            import stucco_evolution
        
            engine = sqlalchemy.create_engine(...)
        
            with engine.begin() as connection: # engine.begin() since SQLAlchemy 0.7.6
                stucco_evolution.initialize(connection)
                stucco_evolution.create_or_upgrade_packages(connection, 'mypackage')
        
        In this pattern, stucco_evolution tries to create the schema for
        `mypackage` and all its dependencies, in topological order, if they
        are not currently tracked in the stucco_evolution table. `create.py`
        will only ever be called once for a particular package, so the evolution
        scripts must be responsible for creating new tables added in a particular
        `VERSION` of the schema.
        
        Eventually `mypackage` will need a new `VERSION`. To do this, you must
        increment `VERSION` to N and add `evolve/evolveN.py` to the evolution
        module.
        
        `evolve/__init__.py`::
        
        	NAME = 'mypackage'
        	VERSION = 1
        	DEPENDS = []
        
        `evolve/evolve1.py`::
        
        	def evolve(connection):
        	    connection.execute("CREATE TABLE foo (bar INTEGER)")
        	    connection.execute("ALTER TABLE baz ADD COLUMN quux INTEGER")
        
        The next time you call `create_or_upgrade(...)`, stucco_evolution will
        notice `mymodule` is already tracked in the stucco_evolution table but
        its database version less than `mymodule.evolve.VERSION`. To rectify,
        stucco_evolution calls each evolveN.py greater than the database version
        in order to bring the database up to date.
        
        In case of dependencies, `stucco_evolution` will try to create or bring
        each dependency package fully up-to-date before trying to upgrade its
        dependent packages. Dependency support is an experimental feature.
        
        Omitted features
        ----------------
        
        There is no provision for downgrade scripts. I used to write them myself
        but I never used them. Instead, back up your database and test against
        a temporary testing database.
        
        There is no DDL abstraction library. Feel free to use any one you like, or
        just write the ALTER TABLE statements yourself.
        
        Robust upgrade scripts
        ----------------------
        
        If you are arrogant enough to release your package as a dependency to another
        package or if it will be widely installed, you need to make sure your upgrade
        scripts are robust. The most important rule:
        
        * New code must never change the output of old evolution scripts.
        
        The simplest way to do this is to issue all DDL as text and never import
        your package in evolve scripts or call SQLAlchemy's create_all()
        except in the create script. You could also try copying and pasting
        your model into each evolve script, as suggested by sqlalchemy-migrate,
        so SQLAlchemy can generate the DDL. You could keep backups of each version
        of the schema and write tests that restore each backup and upgrade to the
        latest version to make sure this remains possible for all prior versions.
        
        
        
        0.4
        ---
        - create_many() checks whether schema has been installed
        
        0.35
        ----
        - fix manifest to properly include paster template
        - remove unnecessary argparse dependency
        
        0.34
        ----
        - add `paster create -t stucco_evolution mypackage` to create an evolution
          module in `mypackage/evolve/...`
        
        0.33
        ----
        - Backwards-incompatible change. A SQLAlchemy connection is now required
          everywhere a session was previously expected.
          This is necessary for transactional DDL (the ability to roll back a
          migration that throws an exception.)
        
        0.12
        ----
        - Add create_or_upgrade_packages(session, 'packagename') convenience function
        
        0.11
        ----
        - Backwards-incompatible API changes
        - Improve documentation
        - Detect circular dependencies between evolution modules
        - Regain 100% statement coverage (however, unit tests depend on several
          unreleased packages)
        
        0.10
        ----
        - Add multi-package schema evolution support with DAG-ordered dependencies
        
        0.9
        ---
        
        - Rename to stucco_evolution
        - stucco_evolution's own upgrade() will now deletage all
          stucco_evolution.Base.metadata.create_all(session) to the evolveN.py
          scripts. This avoids 'DROP TABLE' statements when an upgrade includes
          table renames.
        
        0.8998
        ------
        
        - Improved packageability (MANIFEST.in specified)
        - SQLAlchemyEvolutionManager no longer calls session.commit(); this is
          your responsibility after the migration has completed.
        
        0.8
        ---
        
        - 100% statement coverage
        
        0.0
        ---
        
        -  Initial version
        
Keywords: sqlalchemy stucco
Platform: UNKNOWN
Classifier: Programming Language :: Python
Classifier: License :: OSI Approved :: BSD License
Classifier: Intended Audience :: Developers
Classifier: Topic :: Database :: Front-Ends
Obsoletes: ponzi_evolution
