diff options
Diffstat (limited to 'docs/build/api/operations.rst')
-rw-r--r-- | docs/build/api/operations.rst | 123 |
1 files changed, 123 insertions, 0 deletions
diff --git a/docs/build/api/operations.rst b/docs/build/api/operations.rst new file mode 100644 index 0000000..d9ff238 --- /dev/null +++ b/docs/build/api/operations.rst @@ -0,0 +1,123 @@ +.. _alembic.operations.toplevel: + +===================== +The Operations Object +===================== + +Within migration scripts, actual database migration operations are handled +via an instance of :class:`.Operations`. The :class:`.Operations` class +lists out available migration operations that are linked to a +:class:`.MigrationContext`, which communicates instructions originated +by the :class:`.Operations` object into SQL that is sent to a database or SQL +output stream. + +Most methods on the :class:`.Operations` class are generated dynamically +using a "plugin" system, described in the next section +:ref:`operation_plugins`. Additionally, when Alembic migration scripts +actually run, the methods on the current :class:`.Operations` object are +proxied out to the ``alembic.op`` module, so that they are available +using module-style access. + +For an overview of how to use an :class:`.Operations` object directly +in programs, as well as for reference to the standard operation methods +as well as "batch" methods, see :ref:`ops`. + +.. _operation_plugins: + +Operation Plugins +===================== + +The Operations object is extensible using a plugin system. This system +allows one to add new ``op.<some_operation>`` methods at runtime. The +steps to use this system are to first create a subclass of +:class:`.MigrateOperation`, register it using the :meth:`.Operations.register_operation` +class decorator, then build a default "implementation" function which is +established using the :meth:`.Operations.implementation_for` decorator. + +.. versionadded:: 0.8.0 - the :class:`.Operations` class is now an + open namespace that is extensible via the creation of new + :class:`.MigrateOperation` subclasses. + +Below we illustrate a very simple operation ``CreateSequenceOp`` which +will implement a new method ``op.create_sequence()`` for use in +migration scripts:: + + from alembic.operations import Operations, MigrateOperation + + @Operations.register_operation("create_sequence") + class CreateSequenceOp(MigrateOperation): + """Create a SEQUENCE.""" + + def __init__(self, sequence_name, **kw): + self.sequence_name = sequence_name + self.kw = kw + + @classmethod + def create_sequence(cls, operations, sequence_name, **kw): + """Issue a "CREATE SEQUENCE" instruction.""" + + op = CreateSequenceOp(sequence_name, **kw) + return operations.invoke(op) + +Above, the ``CreateSequenceOp`` class represents a new operation that will +be available as ``op.create_sequence()``. The reason the operation +is represented as a stateful class is so that an operation and a specific +set of arguments can be represented generically; the state can then correspond +to different kinds of operations, such as invoking the instruction against +a database, or autogenerating Python code for the operation into a +script. + +In order to establish the migrate-script behavior of the new operation, +we use the :meth:`.Operations.implementation_for` decorator:: + + @Operations.implementation_for(CreateSequenceOp) + def create_sequence(operations, operation): + operations.execute("CREATE SEQUENCE %s" % operation.sequence_name) + +Above, we use the simplest possible technique of invoking our DDL, which +is just to call :meth:`.Operations.execute` with literal SQL. If this is +all a custom operation needs, then this is fine. However, options for +more comprehensive support include building out a custom SQL construct, +as documented at :ref:`sqlalchemy.ext.compiler_toplevel`. + +With the above two steps, a migration script can now use a new method +``op.create_sequence()`` that will proxy to our object as a classmethod:: + + def upgrade(): + op.create_sequence("my_sequence") + +The registration of new operations only needs to occur in time for the +``env.py`` script to invoke :meth:`.MigrationContext.run_migrations`; +within the module level of the ``env.py`` script is sufficient. + + +.. versionadded:: 0.8 - the migration operations available via the + :class:`.Operations` class as well as the ``alembic.op`` namespace + is now extensible using a plugin system. + + +.. _operation_objects: + +Built-in Operation Objects +============================== + +The migration operations present on :class:`.Operations` are themselves +delivered via operation objects that represent an operation and its +arguments. All operations descend from the :class:`.MigrateOperation` +class, and are registered with the :class:`.Operations` class using +the :meth:`.Operations.register_operation` class decorator. The +:class:`.MigrateOperation` objects also serve as the basis for how the +autogenerate system renders new migration scripts. + +.. seealso:: + + :ref:`operation_plugins` + + :ref:`customizing_revision` + +The built-in operation objects are listed below. + +.. _alembic.operations.ops.toplevel: + +.. automodule:: alembic.operations.ops + :members: |