{ "info": { "author": "Richard Gomes http://rgomes-info.blogspot.com", "author_email": "rgomes.info@gmail.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 3 - Alpha", "Environment :: Console", "Intended Audience :: Developers", "License :: OSI Approved :: BSD License", "Operating System :: OS Independent", "Programming Language :: Cython", "Programming Language :: Python" ], "description": "distcontrib-migrate\n===================\n\n| Code_ | Bugs_ | Forums_ | License_ | Contact_\n\n.. _Code : http://code.launchpad.net/distcontrib-migrate\n.. _Bugs : http://bugs.launchpad.net/distcontrib-migrate\n.. _Forums : http://answers.launchpad.net/distcontrib-migrate\n.. _License : http://opensource.org/licenses/BSD-3-Clause\n.. _Contact : http://launchpad.net/~frgomes\n\nPython package ``distcontrib-migrate`` contributes utility functions to Distutils, extending\nits functionalities, such as database management functions and database migration functions.\n\nThe primary reason for the existence of ``distcontrib-migrate`` is making life a lot easier\nwhen dealing with database management and schema migration. By wiring\n``distcontrib-migrate`` into your ``setup.py`` file, you make it capable of performing these\ntasks for you, thanks to powerful packages `sqlalchemy`_ and `sqlalchemy-migrate`_.\n\n\nSee also: `distcontrib`_\n\nUsage\n-----\n\nBelow you see an example of a ``setup.py`` file which employs `distcontrib`_ and ``distcontrib-migrate``::\n\n #!/usr/bin/env python\n \n from distutils.core import setup\n from Cython.Distutils import build_ext as cython_build\n import distcontrib.tools as du\n import distcontrib_migrate.api as dm\n \n ##\n # This block contains settings you will eventually need to change\n ###\n \n import myapp as myapp #--- adjust to your package name\n\n PACKAGE = myapp.pkg_name\n VERSION = myapp.pkg_version\n DESCRIPTION = myapp.pkg_description\n LICENSE = myapp.pkg_license\n URL = myapp.pkg_url\n AUTHOR = myapp.pkg_author\n AUTHOR_EMAIL = myapp.pkg_email\n KEYWORDS = myapp.pkg_keywords\n REQUIREMENTS = myapp.pkg_requirements\n LONG_DESCRIPTION = du.tools.read('README')\n CLASSIFIERS = [ 'License :: ' + LICENSE,\n 'Operating System :: OS Independent',\n 'Programming Language :: Python',\n 'Programming Language :: Cython',\n 'Development Status :: 3 - Alpha',\n 'Intended Audience :: Developers',\n 'Environment :: Console' ]\n \n ##\n # From this point on, it's unlikely you will be changing anything.\n ###\n \n PACKAGES = find_packages(exclude=[\"*.tests\", \"*.tests.*\", \"tests.*\", \"tests\"])\n PACKAGES_DATA = du.tools.findall_package_data(PACKAGES)\n EXT_MODULES = du.tools.find_ext_modules(PACKAGES)\n \n setup(\n name=PACKAGE,\n version=VERSION,\n description=DESCRIPTION,\n url=URL,\n author=AUTHOR,\n author_email=AUTHOR_EMAIL,\n long_description=LONG_DESCRIPTION,\n license=LICENSE,\n keywords=KEYWORDS,\n classifiers=CLASSIFIERS,\n packages=PACKAGES,\n package_data=PACKAGES_DATA,\n cmdclass={ 'build_ext' : cython_build,\n 'doctest' : du.doctests,\n 'zap' : du.zap,\n 'migrate' : dm.migrate,\n 'psql' : dm.psql, },\n ext_modules=EXT_MODULES,\n # install_requires=REQUIREMENTS\n )\n\nThen create under your ``myapp/__init__.py`` file something like this::\n\n #!/usr/bin/env python\n \n pkg_name = __name__ if __package__ is None else __package__\n pkg_description = 'This application does everything you can imagine'\n pkg_version = '0.1.0'\n pkg_license = 'OSI Approved :: BSD License'\n pkg_url = 'http://' + pkg_name + '.readthedocs.org/'\n pkg_author = 'Richard Gomes http://rgomes-info.blogspot.com'\n pkg_email = 'rgomes.info@gmail.com'\n pkg_keywords = [ 'artificial','intelligence','magic','sorcery','voodoo' ]\n pkg_requirements = [ 'lxml', 'sqlalchemy' ]\n\n\nRequirements\n^^^^^^^^^^^^\n\nDatabase management functions require ``sudo`` rights.\n\n\nQuick guide for the impatient\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nIn *all examples below*, please keep in mind that you can always specify the ``--url`` parameter. If not specified, the value assumed by default is::\n\n postgresql://${USER}@localhost:5432/sample\n\nYou can create users easily from command line::\n\n $ python setup.py psql --createuser # creates an user in the database\n $ python setup.py psql --dropdb # drops user and all owned objects\n $ python setup.py psql --dropdb --createdb # drops and creates an user in one go\n\nThen you can create a Postgres database easily from command line::\n\n $ python setup.py psql --createdb # creates a database\n $ python setup.py psql --dropdb # drops a database\n $ python setup.py psql --dropdb --createdb # drops and creates a database in one go\n\nYou can query what the model version and the database version are::\n\n $ python setup.py migrate --status --url postgresql://${USER}@localhost:5432/sample # show model and database versions\n $ python setup.py migrate --status # same as above\n\nYou can perform upgrade and downgrade the database easily from command line::\n\n $ python setup.py migrate --upgrade --url postgresql://${USER}@localhost:5432/sample # upgrade database\n $ python setup.py migrate --upgrade # same as above\n $ python setup.py migrate --upgrade --changeset=17 # upgrade to database version 17\n $ python setup.py migrate --downgrade --url postgresql://${USER}@localhost:5432/sample # downgrade database\n $ python setup.py migrate --downgrade # same as above\n $ python setup.py migrate --downgrade --changeset=15 # downgrade to database version 15\n\nIn order to test upgrade/downgrade scripts, you can do this::\n\n $ python setup.py migrate --test\n\n.. note:: ``--test`` is equirevalent to ``--upgrade`` followed by ``--downgrade``\n\nIf you have an existing database which you would like to reverse engineer its model, you can try this::\n\n $ STAGING_URL=postgresql://admin@staging.example.com:5432/crm_staging\n $ python setup.py migrate --status --url=${STAGING_URL}\n Model version: 0\n Database version: 17\n $ python setup.py migrate --create-model --url=${STAGING_URL} # reverse engineering to repository \"admin\" (the default)\n $ python setup.py migrate --status --url=${STAGING_URL}\n Model version: 1\n Database version: 17\n\nNow apply the model you obtained to a brand new database::\n\n $ DEVEL_URL=postgresql://localhost:5432/sandbox\n $ python setup.py psql --createuser --url=${DEVEL_URL}\n $ python setup.py psql --createdb --url=${DEVEL_URL}\n $ python setup.py migrate --status --url=${DEVEL_URL}\n Model version: 1\n Database version: 0\n $ python setup.py migrate --upgrade --url=${DEVEL_URL}\n $ python setup.py migrate --status --url=${DEVEL_URL}\n Model version: 1\n Database version: 1\n\n\nConcepts\n--------\n\nAll concepts presented here must be understood from the point of view of the\n``migration`` command, which means that they have a much narrow scope than usual.\n\nMigration script\n^^^^^^^^^^^^^^^^\n\nA migration script is a Python program which has basically only two functions:\n``upgrade`` and ``downgrade``. Below you see an example of a migration script::\n\n from sqlalchemy import *\n meta = MetaData()\n\n exchange_codes = Table('exchange_codes', meta,\n Column('mic', String, primary_key=True, nullable=False),\n Column('country', String, nullable=False),\n Column('iso3166', String, nullable=False),\n Column('omic', String, nullable=False),\n Column('os', String, nullable=False),\n Column('name', String, nullable=False),\n Column('acronym', String, nullable=False),\n Column('city', String, nullable=False),\n Column('url', String, nullable=False),\n Column('status', String, nullable=False),\n Column('sdata', String, nullable=False),\n Column('cdate', String, nullable=False),\n Column('comments', String, nullable=False),\n )\n\n def upgrade(migrate_engine):\n meta.bind = migrate_engine\n exchange_codes.create(meta.bind)\n\n def downgrade(migrate_engine):\n meta.bind = migrate_engine\n exchange_codes.drop(meta.bind)\n\nFor more information, please consult `sqlalchemy-migrate`_\n\n.. tip:: ``distcontrib-migrate`` eases your life in regards to ``sqlalchemy-migrate``: the only task left to you is the maintenance of migrations scripts. You don't need to create the model repository, define the project name, for example.\n\n\nModel version\n^^^^^^^^^^^^^\n\nA model consists a set of migration scripts.\n\nSupose that you are creating CRM application. You start by representing people\nin the database. You think that *name* and *SSN* is all you need for a person,\ninitially. As time passes, you also need to represent deparments in the database.\nThen you realize that you need to link people and departments. Your model would\nhave three iterations:\n\n - 001_creating_table_person\n - 002_creating_table_department\n - 003_linking_people_and_departments\n\nIn other works, your model consists of three migration scripts. When you run the\ncommand ``migrate --status``, it basically tells you how many migration scripts you\nhave defined.\n\n\nDatabase version\n^^^^^^^^^^^^^^^^\n\nSuppose you have defined a model consisting of three migration scripts, like\nexplained above. Also suppose that you created an empty database, which means\nthat no migration scripts have been applied yet. In this case, the\n``migrate --status`` command will show::\n\n $ python setup.py migrate --status\n Model version: 3\n Database version: 0\n\n\nNow suppose you have applied only two migration scripts because you are still\nworking on the code which links people with departments. the ``migrate --status``\ncommand will show::\n\n $ python setup.py migrate --upgrade --changeset=2\n $ python setup.py migrate --status\n Model version: 3\n Database version: 2\n\n\nRepository\n^^^^^^^^^^\n\nA repository is the location in the file system where your model is stored.\nThe repository consists on control files which are *automagically* created\nfor you and migration scripts. You don't need to bother about creating a\nrepository, since it is created by you the first time you run the\n``migrate --status`` command.\n\n\nCreating an empty model\n^^^^^^^^^^^^^^^^^^^^^^^\n\nSupposing you are starting from scratch::\n\n $ python setup.py migrate --status\n Model version: 0\n Database version: 0\n\nIn the example above, a new repository is created under the directory\n``admin``. You can choose another directory name if you pass argument\n``--scripts``, like this::\n\n $ python setup.py migrate --status --scripts=woodpecker\n Model version: 0\n Database version: 0\n\n\n\nCreating a model using reverse engineering\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nThe command ``migrate --create-model`` retrieves the database schema from an\nexisting database accessible thru a connection URL and creates a new migration\nscript onto a giving repository. For example::\n\n $ STAGING_URL=postgresql://admin@staging.example.com:5432/crm_staging\n $ python setup.py migrate --status --url=${STAGING_URL}\n Model version: 0\n Database version: 17\n\n $ python setup.py migrate --create-model --url=${STAGING_URL} # reverse engineering to repository \"admin\" (the default)\n $ python setup.py migrate --status --url=${STAGING_URL}\n Model version: 1\n Database version: 17\n\nThis functionality depends on `sqlalchemy-migrate`_ and it is considered\nexperimental. If you find issues, pleare report to `sqlalchemy-migrate user's mailing list`_\n\n\nAuthentication\n^^^^^^^^^^^^^^\n\nCommands ``migrate`` and ``psql`` also honour the convention of storing passwords\nfor Postgres databases onto file ``~/.pgpass``. The first time you try to access\na database which does not have its password stored in ``~/.pgpass``, you will be\nprompted to enter the password and it will be stored in the file.\n\n\nKnown issues and limitations\n----------------------------\n\n - `(issue 1208083)`_: Installation with ``pip`` onto a fresh environment may fail. Workaround: attempting to install a second time is expected to work::\n\n $ pip install sqlalchemy-migrate # eventually may fail\n $ pip install sqlalchemy-migrate # expected to suceed\n\n - Database management functions (createuser, dropuser, createdb, dropdb) support only Postgres databases at the moment. However, database migrations are supported on all databases supported by `sqlalchemy`_.\n\n.. _`(issue 1208083)`: https://bugs.launchpad.net/distcontrib-migrate/+bug/1208083\n\n\nSupport\n-------\n\n - Bugs: https://bugs.launchpad.net/distcontrib-migrate\n - Forums : https://answers.launchpad.net/distcontrib-migrate\n - Sources: https://code.launchpad.net/distcontrib-migrate\n\n.. note:: Issues related to command ``--create-model`` are, in most situations, originated in `sqlalchemy-migrate`_, since the reverse engineering is considered experimental. Please report these issues at `sqlalchemy-migrate user's mailing list`_.\n\n.. _`distcontrib`: http://distcontrib.readthedocs.org/\n.. _`sqlalchemy`: http://www.sqlalchemy.org/\n.. _`sqlalchemy-migrate`: http://sqlalchemy-migrate.readthedocs.org\n.. _`sqlalchemy-migrate user's mailing list`: http://groups.google.com/group/migrate-users", "description_content_type": null, "docs_url": null, "download_url": "UNKNOWN", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "http://distcontrib-migrate.readthedocs.org/", "keywords": "distribute,setuptools,pip,sqlalchemy,migrate", "license": "OSI Approved :: BSD License", "maintainer": null, "maintainer_email": null, "name": "distcontrib-migrate", "package_url": "https://pypi.org/project/distcontrib-migrate/", "platform": "UNKNOWN", "project_url": "https://pypi.org/project/distcontrib-migrate/", "project_urls": { "Download": "UNKNOWN", "Homepage": "http://distcontrib-migrate.readthedocs.org/" }, "release_url": "https://pypi.org/project/distcontrib-migrate/0.1.1/", "requires_dist": null, "requires_python": null, "summary": "Contributions to Distutils", "version": "0.1.1" }, "last_serial": 836198, "releases": { "0.1.0": [ { "comment_text": "", "digests": { "md5": "7bcd08b04e0b126c271525fa56614108", "sha256": "1a263778524401576c8254c9c3e4009ec7436566179ab3ce02f50fcdfae99a15" }, "downloads": -1, "filename": "distcontrib-migrate-0.1.0.tar.gz", "has_sig": false, "md5_digest": "7bcd08b04e0b126c271525fa56614108", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 12846, "upload_time": "2013-08-05T11:52:51", "url": "https://files.pythonhosted.org/packages/34/84/829c5a69e4aa00b7fca813deac658a25e8b1824e4ac86722ccc846c4cd13/distcontrib-migrate-0.1.0.tar.gz" } ], "0.1.1": [ { "comment_text": "", "digests": { "md5": "7d1435a43d0514b069d261d5db217558", "sha256": "a71d36622f084183d37c9405f5036c19369d27353df576e554a470d0ed9913e9" }, "downloads": -1, "filename": "distcontrib-migrate-0.1.1.tar.gz", "has_sig": false, "md5_digest": "7d1435a43d0514b069d261d5db217558", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 12857, "upload_time": "2013-08-09T02:12:20", "url": "https://files.pythonhosted.org/packages/7d/fc/8cb8844adc4d23e0c5506c5bf9a0400b98dffea96becdd3f57c451655bb4/distcontrib-migrate-0.1.1.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "7d1435a43d0514b069d261d5db217558", "sha256": "a71d36622f084183d37c9405f5036c19369d27353df576e554a470d0ed9913e9" }, "downloads": -1, "filename": "distcontrib-migrate-0.1.1.tar.gz", "has_sig": false, "md5_digest": "7d1435a43d0514b069d261d5db217558", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 12857, "upload_time": "2013-08-09T02:12:20", "url": "https://files.pythonhosted.org/packages/7d/fc/8cb8844adc4d23e0c5506c5bf9a0400b98dffea96becdd3f57c451655bb4/distcontrib-migrate-0.1.1.tar.gz" } ] }