1.. _alembic.operations.toplevel: 2 3===================== 4Operation Directives 5===================== 6 7.. note:: this section discusses the **internal API of Alembic** as regards 8 the internal system of defining migration operation directives. 9 This section is only useful for developers who wish to extend the 10 capabilities of Alembic. For end-user guidance on Alembic migration 11 operations, please see :ref:`ops`. 12 13Within migration scripts, actual database migration operations are handled 14via an instance of :class:`.Operations`. The :class:`.Operations` class 15lists out available migration operations that are linked to a 16:class:`.MigrationContext`, which communicates instructions originated 17by the :class:`.Operations` object into SQL that is sent to a database or SQL 18output stream. 19 20Most methods on the :class:`.Operations` class are generated dynamically 21using a "plugin" system, described in the next section 22:ref:`operation_plugins`. Additionally, when Alembic migration scripts 23actually run, the methods on the current :class:`.Operations` object are 24proxied out to the ``alembic.op`` module, so that they are available 25using module-style access. 26 27For an overview of how to use an :class:`.Operations` object directly 28in programs, as well as for reference to the standard operation methods 29as well as "batch" methods, see :ref:`ops`. 30 31.. _operation_plugins: 32 33Operation Plugins 34===================== 35 36The Operations object is extensible using a plugin system. This system 37allows one to add new ``op.<some_operation>`` methods at runtime. The 38steps to use this system are to first create a subclass of 39:class:`.MigrateOperation`, register it using the :meth:`.Operations.register_operation` 40class decorator, then build a default "implementation" function which is 41established using the :meth:`.Operations.implementation_for` decorator. 42 43.. versionadded:: 0.8.0 - the :class:`.Operations` class is now an 44 open namespace that is extensible via the creation of new 45 :class:`.MigrateOperation` subclasses. 46 47Below we illustrate a very simple operation ``CreateSequenceOp`` which 48will implement a new method ``op.create_sequence()`` for use in 49migration scripts:: 50 51 from alembic.operations import Operations, MigrateOperation 52 53 @Operations.register_operation("create_sequence") 54 class CreateSequenceOp(MigrateOperation): 55 """Create a SEQUENCE.""" 56 57 def __init__(self, sequence_name, schema=None): 58 self.sequence_name = sequence_name 59 self.schema = schema 60 61 @classmethod 62 def create_sequence(cls, operations, sequence_name, **kw): 63 """Issue a "CREATE SEQUENCE" instruction.""" 64 65 op = CreateSequenceOp(sequence_name, **kw) 66 return operations.invoke(op) 67 68 def reverse(self): 69 # only needed to support autogenerate 70 return DropSequenceOp(self.sequence_name, schema=self.schema) 71 72 @Operations.register_operation("drop_sequence") 73 class DropSequenceOp(MigrateOperation): 74 """Drop a SEQUENCE.""" 75 76 def __init__(self, sequence_name, schema=None): 77 self.sequence_name = sequence_name 78 self.schema = schema 79 80 @classmethod 81 def drop_sequence(cls, operations, sequence_name, **kw): 82 """Issue a "DROP SEQUENCE" instruction.""" 83 84 op = DropSequenceOp(sequence_name, **kw) 85 return operations.invoke(op) 86 87 def reverse(self): 88 # only needed to support autogenerate 89 return CreateSequenceOp(self.sequence_name, schema=self.schema) 90 91Above, the ``CreateSequenceOp`` and ``DropSequenceOp`` classes represent 92new operations that will 93be available as ``op.create_sequence()`` and ``op.drop_sequence()``. 94The reason the operations 95are represented as stateful classes is so that an operation and a specific 96set of arguments can be represented generically; the state can then correspond 97to different kinds of operations, such as invoking the instruction against 98a database, or autogenerating Python code for the operation into a 99script. 100 101In order to establish the migrate-script behavior of the new operations, 102we use the :meth:`.Operations.implementation_for` decorator:: 103 104 @Operations.implementation_for(CreateSequenceOp) 105 def create_sequence(operations, operation): 106 if operation.schema is not None: 107 name = "%s.%s" % (operation.schema, operation.sequence_name) 108 else: 109 name = operation.sequence_name 110 operations.execute("CREATE SEQUENCE %s" % name) 111 112 113 @Operations.implementation_for(DropSequenceOp) 114 def drop_sequence(operations, operation): 115 if operation.schema is not None: 116 name = "%s.%s" % (operation.schema, operation.sequence_name) 117 else: 118 name = operation.sequence_name 119 operations.execute("DROP SEQUENCE %s" % name) 120 121Above, we use the simplest possible technique of invoking our DDL, which 122is just to call :meth:`.Operations.execute` with literal SQL. If this is 123all a custom operation needs, then this is fine. However, options for 124more comprehensive support include building out a custom SQL construct, 125as documented at :ref:`sqlalchemy.ext.compiler_toplevel`. 126 127With the above two steps, a migration script can now use new methods 128``op.create_sequence()`` and ``op.drop_sequence()`` that will proxy to 129our object as a classmethod:: 130 131 def upgrade(): 132 op.create_sequence("my_sequence") 133 134 def downgrade(): 135 op.drop_sequence("my_sequence") 136 137The registration of new operations only needs to occur in time for the 138``env.py`` script to invoke :meth:`.MigrationContext.run_migrations`; 139within the module level of the ``env.py`` script is sufficient. 140 141.. seealso:: 142 143 :ref:`autogen_custom_ops` - how to add autogenerate support to 144 custom operations. 145 146.. versionadded:: 0.8 - the migration operations available via the 147 :class:`.Operations` class as well as the ``alembic.op`` namespace 148 is now extensible using a plugin system. 149 150 151.. _operation_objects: 152.. _alembic.operations.ops.toplevel: 153 154Built-in Operation Objects 155============================== 156 157The migration operations present on :class:`.Operations` are themselves 158delivered via operation objects that represent an operation and its 159arguments. All operations descend from the :class:`.MigrateOperation` 160class, and are registered with the :class:`.Operations` class using 161the :meth:`.Operations.register_operation` class decorator. The 162:class:`.MigrateOperation` objects also serve as the basis for how the 163autogenerate system renders new migration scripts. 164 165.. seealso:: 166 167 :ref:`operation_plugins` 168 169 :ref:`customizing_revision` 170 171The built-in operation objects are listed below. 172 173.. automodule:: alembic.operations.ops 174 :members: 175