From: Mike Bayer Date: Tue, 4 Mar 2014 23:24:15 +0000 (-0500) Subject: - add new section, cookbook. First example, add conditonal sections to migrations X-Git-Tag: rel_0_6_4~15 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=334e04d710f16a04ce4d9ed737ec2d0a02b11de4;p=thirdparty%2Fsqlalchemy%2Falembic.git - add new section, cookbook. First example, add conditonal sections to migrations within script.py.mako. fixes #177 --- diff --git a/docs/build/cookbook.rst b/docs/build/cookbook.rst new file mode 100644 index 00000000..6a07e4dd --- /dev/null +++ b/docs/build/cookbook.rst @@ -0,0 +1,144 @@ +======== +Cookbook +======== + +A collection of "How-Tos", highlighting various ways to extend +Alembic. + +.. note:: + + This is a new section where we hope to start cataloguing various "how-tos" + we come up with based on user requests. It is often the case that users + will request a feature only to learn that simple customization can + provide the same thing. There's only one recipe at the moment but + we hope to get more soon! + +Conditional Migration Elements +============================== + +This example features the basic idea of a common need, that of affecting +how a migration runs based on command line switches. + +The technique to use here is simple; within a migration script, inspect +the :meth:`.EnvironmentContext.get_x_argument` collection for any additional, +user-defined parameters. Then take action based on the presence of those +arguments. + +To make it such that the logic to inspect these flags is easy to use and +modify, we modify our ``script.py.mako`` template to make this feature +available in all new revision files: + +.. code-block:: mako + + """${message} + + Revision ID: ${up_revision} + Revises: ${down_revision} + Create Date: ${create_date} + + """ + + # revision identifiers, used by Alembic. + revision = ${repr(up_revision)} + down_revision = ${repr(down_revision)} + + from alembic import op + import sqlalchemy as sa + ${imports if imports else ""} + + from alembic import context + + + def upgrade(): + schema_upgrades() + if context.get_x_argument(as_dictionary=True).get('data', None): + data_upgrades() + + def downgrade(): + if context.get_x_argument(as_dictionary=True).get('data', None): + data_downgrades() + schema_downgrades() + + def schema_upgrades(): + """schema upgrade migrations go here.""" + ${upgrades if upgrades else "pass"} + + def schema_downgrades(): + """schema downgrade migrations go here.""" + ${downgrades if downgrades else "pass"} + + def data_upgrades(): + """Add any optional data upgrade migrations here!""" + pass + + def data_downgrades(): + """Add any optional data downgrade migrations here!""" + pass + +Now, when we create a new migration file, the ``data_upgrades()`` and ``data_downgrades()`` +placeholders will be available, where we can add optional data migrations:: + + """rev one + + Revision ID: 3ba2b522d10d + Revises: None + Create Date: 2014-03-04 18:05:36.992867 + + """ + + # revision identifiers, used by Alembic. + revision = '3ba2b522d10d' + down_revision = None + + from alembic import op + import sqlalchemy as sa + from sqlalchemy import String, Column + from sqlalchemy.sql import table, column + + from alembic import context + + def upgrade(): + schema_upgrades() + if context.get_x_argument(as_dictionary=True).get('data', None): + data_upgrades() + + def downgrade(): + if context.get_x_argument(as_dictionary=True).get('data', None): + data_downgrades() + schema_downgrades() + + def schema_upgrades(): + """schema upgrade migrations go here.""" + op.create_table("my_table", Column('data', String)) + + def schema_downgrades(): + """schema downgrade migrations go here.""" + op.drop_table("my_table") + + def data_upgrades(): + """Add any optional data upgrade migrations here!""" + + my_table = table('my_table', + column('data', String), + ) + + op.bulk_insert(my_table, + [ + {'data': 'data 1'}, + {'data': 'data 2'}, + {'data': 'data 3'}, + ] + ) + + def data_downgrades(): + """Add any optional data downgrade migrations here!""" + + op.execute("delete from my_table") + +To invoke our migrations with data included, we use the ``-x`` flag:: + + alembic -x data=true upgrade head + +The :meth:`.EnvironmentContext.get_x_argument` is an easy way to support +new commandline options within environment and migration scripts. + diff --git a/docs/build/index.rst b/docs/build/index.rst index 4e8b5360..fb7efc69 100644 --- a/docs/build/index.rst +++ b/docs/build/index.rst @@ -11,6 +11,7 @@ with the `SQLAlchemy `_ Database Toolkit for Python. front tutorial ops + cookbook api changelog