Coverage for /home/martinb/.local/share/virtualenvs/camcops/lib/python3.6/site-packages/alembic/runtime/environment.py : 28%

Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1from .migration import MigrationContext
2from .. import util
3from ..operations import Operations
6class EnvironmentContext(util.ModuleClsProxy):
8 """A configurational facade made available in an ``env.py`` script.
10 The :class:`.EnvironmentContext` acts as a *facade* to the more
11 nuts-and-bolts objects of :class:`.MigrationContext` as well as certain
12 aspects of :class:`.Config`,
13 within the context of the ``env.py`` script that is invoked by
14 most Alembic commands.
16 :class:`.EnvironmentContext` is normally instantiated
17 when a command in :mod:`alembic.command` is run. It then makes
18 itself available in the ``alembic.context`` module for the scope
19 of the command. From within an ``env.py`` script, the current
20 :class:`.EnvironmentContext` is available by importing this module.
22 :class:`.EnvironmentContext` also supports programmatic usage.
23 At this level, it acts as a Python context manager, that is, is
24 intended to be used using the
25 ``with:`` statement. A typical use of :class:`.EnvironmentContext`::
27 from alembic.config import Config
28 from alembic.script import ScriptDirectory
30 config = Config()
31 config.set_main_option("script_location", "myapp:migrations")
32 script = ScriptDirectory.from_config(config)
34 def my_function(rev, context):
35 '''do something with revision "rev", which
36 will be the current database revision,
37 and "context", which is the MigrationContext
38 that the env.py will create'''
40 with EnvironmentContext(
41 config,
42 script,
43 fn = my_function,
44 as_sql = False,
45 starting_rev = 'base',
46 destination_rev = 'head',
47 tag = "sometag"
48 ):
49 script.run_env()
51 The above script will invoke the ``env.py`` script
52 within the migration environment. If and when ``env.py``
53 calls :meth:`.MigrationContext.run_migrations`, the
54 ``my_function()`` function above will be called
55 by the :class:`.MigrationContext`, given the context
56 itself as well as the current revision in the database.
58 .. note::
60 For most API usages other than full blown
61 invocation of migration scripts, the :class:`.MigrationContext`
62 and :class:`.ScriptDirectory` objects can be created and
63 used directly. The :class:`.EnvironmentContext` object
64 is *only* needed when you need to actually invoke the
65 ``env.py`` module present in the migration environment.
67 """
69 _migration_context = None
71 config = None
72 """An instance of :class:`.Config` representing the
73 configuration file contents as well as other variables
74 set programmatically within it."""
76 script = None
77 """An instance of :class:`.ScriptDirectory` which provides
78 programmatic access to version files within the ``versions/``
79 directory.
81 """
83 def __init__(self, config, script, **kw):
84 r"""Construct a new :class:`.EnvironmentContext`.
86 :param config: a :class:`.Config` instance.
87 :param script: a :class:`.ScriptDirectory` instance.
88 :param \**kw: keyword options that will be ultimately
89 passed along to the :class:`.MigrationContext` when
90 :meth:`.EnvironmentContext.configure` is called.
92 """
93 self.config = config
94 self.script = script
95 self.context_opts = kw
97 def __enter__(self):
98 """Establish a context which provides a
99 :class:`.EnvironmentContext` object to
100 env.py scripts.
102 The :class:`.EnvironmentContext` will
103 be made available as ``from alembic import context``.
105 """
106 self._install_proxy()
107 return self
109 def __exit__(self, *arg, **kw):
110 self._remove_proxy()
112 def is_offline_mode(self):
113 """Return True if the current migrations environment
114 is running in "offline mode".
116 This is ``True`` or ``False`` depending
117 on the the ``--sql`` flag passed.
119 This function does not require that the :class:`.MigrationContext`
120 has been configured.
122 """
123 return self.context_opts.get("as_sql", False)
125 def is_transactional_ddl(self):
126 """Return True if the context is configured to expect a
127 transactional DDL capable backend.
129 This defaults to the type of database in use, and
130 can be overridden by the ``transactional_ddl`` argument
131 to :meth:`.configure`
133 This function requires that a :class:`.MigrationContext`
134 has first been made available via :meth:`.configure`.
136 """
137 return self.get_context().impl.transactional_ddl
139 def requires_connection(self):
140 return not self.is_offline_mode()
142 def get_head_revision(self):
143 """Return the hex identifier of the 'head' script revision.
145 If the script directory has multiple heads, this
146 method raises a :class:`.CommandError`;
147 :meth:`.EnvironmentContext.get_head_revisions` should be preferred.
149 This function does not require that the :class:`.MigrationContext`
150 has been configured.
152 .. seealso:: :meth:`.EnvironmentContext.get_head_revisions`
154 """
155 return self.script.as_revision_number("head")
157 def get_head_revisions(self):
158 """Return the hex identifier of the 'heads' script revision(s).
160 This returns a tuple containing the version number of all
161 heads in the script directory.
163 This function does not require that the :class:`.MigrationContext`
164 has been configured.
166 .. versionadded:: 0.7.0
168 """
169 return self.script.as_revision_number("heads")
171 def get_starting_revision_argument(self):
172 """Return the 'starting revision' argument,
173 if the revision was passed using ``start:end``.
175 This is only meaningful in "offline" mode.
176 Returns ``None`` if no value is available
177 or was configured.
179 This function does not require that the :class:`.MigrationContext`
180 has been configured.
182 """
183 if self._migration_context is not None:
184 return self.script.as_revision_number(
185 self.get_context()._start_from_rev
186 )
187 elif "starting_rev" in self.context_opts:
188 return self.script.as_revision_number(
189 self.context_opts["starting_rev"]
190 )
191 else:
192 # this should raise only in the case that a command
193 # is being run where the "starting rev" is never applicable;
194 # this is to catch scripts which rely upon this in
195 # non-sql mode or similar
196 raise util.CommandError(
197 "No starting revision argument is available."
198 )
200 def get_revision_argument(self):
201 """Get the 'destination' revision argument.
203 This is typically the argument passed to the
204 ``upgrade`` or ``downgrade`` command.
206 If it was specified as ``head``, the actual
207 version number is returned; if specified
208 as ``base``, ``None`` is returned.
210 This function does not require that the :class:`.MigrationContext`
211 has been configured.
213 """
214 return self.script.as_revision_number(
215 self.context_opts["destination_rev"]
216 )
218 def get_tag_argument(self):
219 """Return the value passed for the ``--tag`` argument, if any.
221 The ``--tag`` argument is not used directly by Alembic,
222 but is available for custom ``env.py`` configurations that
223 wish to use it; particularly for offline generation scripts
224 that wish to generate tagged filenames.
226 This function does not require that the :class:`.MigrationContext`
227 has been configured.
229 .. seealso::
231 :meth:`.EnvironmentContext.get_x_argument` - a newer and more
232 open ended system of extending ``env.py`` scripts via the command
233 line.
235 """
236 return self.context_opts.get("tag", None)
238 def get_x_argument(self, as_dictionary=False):
239 """Return the value(s) passed for the ``-x`` argument, if any.
241 The ``-x`` argument is an open ended flag that allows any user-defined
242 value or values to be passed on the command line, then available
243 here for consumption by a custom ``env.py`` script.
245 The return value is a list, returned directly from the ``argparse``
246 structure. If ``as_dictionary=True`` is passed, the ``x`` arguments
247 are parsed using ``key=value`` format into a dictionary that is
248 then returned.
250 For example, to support passing a database URL on the command line,
251 the standard ``env.py`` script can be modified like this::
253 cmd_line_url = context.get_x_argument(
254 as_dictionary=True).get('dbname')
255 if cmd_line_url:
256 engine = create_engine(cmd_line_url)
257 else:
258 engine = engine_from_config(
259 config.get_section(config.config_ini_section),
260 prefix='sqlalchemy.',
261 poolclass=pool.NullPool)
263 This then takes effect by running the ``alembic`` script as::
265 alembic -x dbname=postgresql://user:pass@host/dbname upgrade head
267 This function does not require that the :class:`.MigrationContext`
268 has been configured.
270 .. versionadded:: 0.6.0
272 .. seealso::
274 :meth:`.EnvironmentContext.get_tag_argument`
276 :attr:`.Config.cmd_opts`
278 """
279 if self.config.cmd_opts is not None:
280 value = self.config.cmd_opts.x or []
281 else:
282 value = []
283 if as_dictionary:
284 value = dict(arg.split("=", 1) for arg in value)
285 return value
287 def configure(
288 self,
289 connection=None,
290 url=None,
291 dialect_name=None,
292 dialect_opts=None,
293 transactional_ddl=None,
294 transaction_per_migration=False,
295 output_buffer=None,
296 starting_rev=None,
297 tag=None,
298 template_args=None,
299 render_as_batch=False,
300 target_metadata=None,
301 include_symbol=None,
302 include_object=None,
303 include_schemas=False,
304 process_revision_directives=None,
305 compare_type=False,
306 compare_server_default=False,
307 render_item=None,
308 literal_binds=False,
309 upgrade_token="upgrades",
310 downgrade_token="downgrades",
311 alembic_module_prefix="op.",
312 sqlalchemy_module_prefix="sa.",
313 user_module_prefix=None,
314 on_version_apply=None,
315 **kw
316 ):
317 """Configure a :class:`.MigrationContext` within this
318 :class:`.EnvironmentContext` which will provide database
319 connectivity and other configuration to a series of
320 migration scripts.
322 Many methods on :class:`.EnvironmentContext` require that
323 this method has been called in order to function, as they
324 ultimately need to have database access or at least access
325 to the dialect in use. Those which do are documented as such.
327 The important thing needed by :meth:`.configure` is a
328 means to determine what kind of database dialect is in use.
329 An actual connection to that database is needed only if
330 the :class:`.MigrationContext` is to be used in
331 "online" mode.
333 If the :meth:`.is_offline_mode` function returns ``True``,
334 then no connection is needed here. Otherwise, the
335 ``connection`` parameter should be present as an
336 instance of :class:`sqlalchemy.engine.Connection`.
338 This function is typically called from the ``env.py``
339 script within a migration environment. It can be called
340 multiple times for an invocation. The most recent
341 :class:`~sqlalchemy.engine.Connection`
342 for which it was called is the one that will be operated upon
343 by the next call to :meth:`.run_migrations`.
345 General parameters:
347 :param connection: a :class:`~sqlalchemy.engine.Connection`
348 to use
349 for SQL execution in "online" mode. When present, is also
350 used to determine the type of dialect in use.
351 :param url: a string database url, or a
352 :class:`sqlalchemy.engine.url.URL` object.
353 The type of dialect to be used will be derived from this if
354 ``connection`` is not passed.
355 :param dialect_name: string name of a dialect, such as
356 "postgresql", "mssql", etc.
357 The type of dialect to be used will be derived from this if
358 ``connection`` and ``url`` are not passed.
359 :param dialect_opts: dictionary of options to be passed to dialect
360 constructor.
362 .. versionadded:: 1.0.12
364 :param transactional_ddl: Force the usage of "transactional"
365 DDL on or off;
366 this otherwise defaults to whether or not the dialect in
367 use supports it.
368 :param transaction_per_migration: if True, nest each migration script
369 in a transaction rather than the full series of migrations to
370 run.
372 .. versionadded:: 0.6.5
374 :param output_buffer: a file-like object that will be used
375 for textual output
376 when the ``--sql`` option is used to generate SQL scripts.
377 Defaults to
378 ``sys.stdout`` if not passed here and also not present on
379 the :class:`.Config`
380 object. The value here overrides that of the :class:`.Config`
381 object.
382 :param output_encoding: when using ``--sql`` to generate SQL
383 scripts, apply this encoding to the string output.
384 :param literal_binds: when using ``--sql`` to generate SQL
385 scripts, pass through the ``literal_binds`` flag to the compiler
386 so that any literal values that would ordinarily be bound
387 parameters are converted to plain strings.
389 .. warning:: Dialects can typically only handle simple datatypes
390 like strings and numbers for auto-literal generation. Datatypes
391 like dates, intervals, and others may still require manual
392 formatting, typically using :meth:`.Operations.inline_literal`.
394 .. note:: the ``literal_binds`` flag is ignored on SQLAlchemy
395 versions prior to 0.8 where this feature is not supported.
397 .. versionadded:: 0.7.6
399 .. seealso::
401 :meth:`.Operations.inline_literal`
403 :param starting_rev: Override the "starting revision" argument
404 when using ``--sql`` mode.
405 :param tag: a string tag for usage by custom ``env.py`` scripts.
406 Set via the ``--tag`` option, can be overridden here.
407 :param template_args: dictionary of template arguments which
408 will be added to the template argument environment when
409 running the "revision" command. Note that the script environment
410 is only run within the "revision" command if the --autogenerate
411 option is used, or if the option "revision_environment=true"
412 is present in the alembic.ini file.
414 :param version_table: The name of the Alembic version table.
415 The default is ``'alembic_version'``.
416 :param version_table_schema: Optional schema to place version
417 table within.
418 :param version_table_pk: boolean, whether the Alembic version table
419 should use a primary key constraint for the "value" column; this
420 only takes effect when the table is first created.
421 Defaults to True; setting to False should not be necessary and is
422 here for backwards compatibility reasons.
424 .. versionadded:: 0.8.10 Added the
425 :paramref:`.EnvironmentContext.configure.version_table_pk`
426 flag and additionally established that the Alembic version table
427 has a primary key constraint by default.
429 :param on_version_apply: a callable or collection of callables to be
430 run for each migration step.
431 The callables will be run in the order they are given, once for
432 each migration step, after the respective operation has been
433 applied but before its transaction is finalized.
434 Each callable accepts no positional arguments and the following
435 keyword arguments:
437 * ``ctx``: the :class:`.MigrationContext` running the migration,
438 * ``step``: a :class:`.MigrationInfo` representing the
439 step currently being applied,
440 * ``heads``: a collection of version strings representing the
441 current heads,
442 * ``run_args``: the ``**kwargs`` passed to :meth:`.run_migrations`.
444 .. versionadded:: 0.9.3
447 Parameters specific to the autogenerate feature, when
448 ``alembic revision`` is run with the ``--autogenerate`` feature:
450 :param target_metadata: a :class:`sqlalchemy.schema.MetaData`
451 object, or a sequence of :class:`~sqlalchemy.schema.MetaData`
452 objects, that will be consulted during autogeneration.
453 The tables present in each :class:`~sqlalchemy.schema.MetaData`
454 will be compared against
455 what is locally available on the target
456 :class:`~sqlalchemy.engine.Connection`
457 to produce candidate upgrade/downgrade operations.
459 .. versionchanged:: 0.9.0 the
460 :paramref:`.EnvironmentContext.configure.target_metadata`
461 parameter may now be passed a sequence of
462 :class:`~sqlalchemy.schema.MetaData` objects to support
463 autogeneration of multiple :class:`~sqlalchemy.schema.MetaData`
464 collections.
466 :param compare_type: Indicates type comparison behavior during
467 an autogenerate
468 operation. Defaults to ``False`` which disables type
469 comparison. Set to
470 ``True`` to turn on default type comparison, which has varied
471 accuracy depending on backend. See :ref:`compare_types`
472 for an example as well as information on other type
473 comparison options.
475 .. seealso::
477 :ref:`compare_types`
479 :paramref:`.EnvironmentContext.configure.compare_server_default`
481 :param compare_server_default: Indicates server default comparison
482 behavior during
483 an autogenerate operation. Defaults to ``False`` which disables
484 server default
485 comparison. Set to ``True`` to turn on server default comparison,
486 which has
487 varied accuracy depending on backend.
489 To customize server default comparison behavior, a callable may
490 be specified
491 which can filter server default comparisons during an
492 autogenerate operation.
493 defaults during an autogenerate operation. The format of this
494 callable is::
496 def my_compare_server_default(context, inspected_column,
497 metadata_column, inspected_default, metadata_default,
498 rendered_metadata_default):
499 # return True if the defaults are different,
500 # False if not, or None to allow the default implementation
501 # to compare these defaults
502 return None
504 context.configure(
505 # ...
506 compare_server_default = my_compare_server_default
507 )
509 ``inspected_column`` is a dictionary structure as returned by
510 :meth:`sqlalchemy.engine.reflection.Inspector.get_columns`, whereas
511 ``metadata_column`` is a :class:`sqlalchemy.schema.Column` from
512 the local model environment.
514 A return value of ``None`` indicates to allow default server default
515 comparison
516 to proceed. Note that some backends such as Postgresql actually
517 execute
518 the two defaults on the database side to compare for equivalence.
520 .. seealso::
522 :paramref:`.EnvironmentContext.configure.compare_type`
524 :param include_object: A callable function which is given
525 the chance to return ``True`` or ``False`` for any object,
526 indicating if the given object should be considered in the
527 autogenerate sweep.
529 The function accepts the following positional arguments:
531 * ``object``: a :class:`~sqlalchemy.schema.SchemaItem` object such
532 as a :class:`~sqlalchemy.schema.Table`,
533 :class:`~sqlalchemy.schema.Column`,
534 :class:`~sqlalchemy.schema.Index`
535 :class:`~sqlalchemy.schema.UniqueConstraint`,
536 or :class:`~sqlalchemy.schema.ForeignKeyConstraint` object
537 * ``name``: the name of the object. This is typically available
538 via ``object.name``.
539 * ``type``: a string describing the type of object; currently
540 ``"table"``, ``"column"``, ``"index"``, ``"unique_constraint"``,
541 or ``"foreign_key_constraint"``
543 .. versionadded:: 0.7.0 Support for indexes and unique constraints
544 within the
545 :paramref:`~.EnvironmentContext.configure.include_object` hook.
547 .. versionadded:: 0.7.1 Support for foreign keys within the
548 :paramref:`~.EnvironmentContext.configure.include_object` hook.
550 * ``reflected``: ``True`` if the given object was produced based on
551 table reflection, ``False`` if it's from a local :class:`.MetaData`
552 object.
553 * ``compare_to``: the object being compared against, if available,
554 else ``None``.
556 E.g.::
558 def include_object(object, name, type_, reflected, compare_to):
559 if (type_ == "column" and
560 not reflected and
561 object.info.get("skip_autogenerate", False)):
562 return False
563 else:
564 return True
566 context.configure(
567 # ...
568 include_object = include_object
569 )
571 :paramref:`.EnvironmentContext.configure.include_object` can also
572 be used to filter on specific schemas to include or omit, when
573 the :paramref:`.EnvironmentContext.configure.include_schemas`
574 flag is set to ``True``. The :attr:`.Table.schema` attribute
575 on each :class:`.Table` object reflected will indicate the name of the
576 schema from which the :class:`.Table` originates.
578 .. versionadded:: 0.6.0
580 .. seealso::
582 :paramref:`.EnvironmentContext.configure.include_schemas`
584 :param include_symbol: A callable function which, given a table name
585 and schema name (may be ``None``), returns ``True`` or ``False``,
586 indicating if the given table should be considered in the
587 autogenerate sweep.
589 .. deprecated:: 0.6.0
590 :paramref:`.EnvironmentContext.configure.include_symbol`
591 is superceded by the more generic
592 :paramref:`.EnvironmentContext.configure.include_object`
593 parameter.
595 E.g.::
597 def include_symbol(tablename, schema):
598 return tablename not in ("skip_table_one", "skip_table_two")
600 context.configure(
601 # ...
602 include_symbol = include_symbol
603 )
605 .. seealso::
607 :paramref:`.EnvironmentContext.configure.include_schemas`
609 :paramref:`.EnvironmentContext.configure.include_object`
611 :param render_as_batch: if True, commands which alter elements
612 within a table will be placed under a ``with batch_alter_table():``
613 directive, so that batch migrations will take place.
615 .. versionadded:: 0.7.0
617 .. seealso::
619 :ref:`batch_migrations`
621 :param include_schemas: If True, autogenerate will scan across
622 all schemas located by the SQLAlchemy
623 :meth:`~sqlalchemy.engine.reflection.Inspector.get_schema_names`
624 method, and include all differences in tables found across all
625 those schemas. When using this option, you may want to also
626 use the :paramref:`.EnvironmentContext.configure.include_object`
627 option to specify a callable which
628 can filter the tables/schemas that get included.
630 .. seealso::
632 :paramref:`.EnvironmentContext.configure.include_object`
634 :param render_item: Callable that can be used to override how
635 any schema item, i.e. column, constraint, type,
636 etc., is rendered for autogenerate. The callable receives a
637 string describing the type of object, the object, and
638 the autogen context. If it returns False, the
639 default rendering method will be used. If it returns None,
640 the item will not be rendered in the context of a Table
641 construct, that is, can be used to skip columns or constraints
642 within op.create_table()::
644 def my_render_column(type_, col, autogen_context):
645 if type_ == "column" and isinstance(col, MySpecialCol):
646 return repr(col)
647 else:
648 return False
650 context.configure(
651 # ...
652 render_item = my_render_column
653 )
655 Available values for the type string include: ``"column"``,
656 ``"primary_key"``, ``"foreign_key"``, ``"unique"``, ``"check"``,
657 ``"type"``, ``"server_default"``.
659 .. seealso::
661 :ref:`autogen_render_types`
663 :param upgrade_token: When autogenerate completes, the text of the
664 candidate upgrade operations will be present in this template
665 variable when ``script.py.mako`` is rendered. Defaults to
666 ``upgrades``.
667 :param downgrade_token: When autogenerate completes, the text of the
668 candidate downgrade operations will be present in this
669 template variable when ``script.py.mako`` is rendered. Defaults to
670 ``downgrades``.
672 :param alembic_module_prefix: When autogenerate refers to Alembic
673 :mod:`alembic.operations` constructs, this prefix will be used
674 (i.e. ``op.create_table``) Defaults to "``op.``".
675 Can be ``None`` to indicate no prefix.
677 :param sqlalchemy_module_prefix: When autogenerate refers to
678 SQLAlchemy
679 :class:`~sqlalchemy.schema.Column` or type classes, this prefix
680 will be used
681 (i.e. ``sa.Column("somename", sa.Integer)``) Defaults to "``sa.``".
682 Can be ``None`` to indicate no prefix.
683 Note that when dialect-specific types are rendered, autogenerate
684 will render them using the dialect module name, i.e. ``mssql.BIT()``,
685 ``postgresql.UUID()``.
687 :param user_module_prefix: When autogenerate refers to a SQLAlchemy
688 type (e.g. :class:`.TypeEngine`) where the module name is not
689 under the ``sqlalchemy`` namespace, this prefix will be used
690 within autogenerate. If left at its default of
691 ``None``, the ``__module__`` attribute of the type is used to
692 render the import module. It's a good practice to set this
693 and to have all custom types be available from a fixed module space,
694 in order to future-proof migration files against reorganizations
695 in modules.
697 .. versionchanged:: 0.7.0
698 :paramref:`.EnvironmentContext.configure.user_module_prefix`
699 no longer defaults to the value of
700 :paramref:`.EnvironmentContext.configure.sqlalchemy_module_prefix`
701 when left at ``None``; the ``__module__`` attribute is now used.
703 .. versionadded:: 0.6.3 added
704 :paramref:`.EnvironmentContext.configure.user_module_prefix`
706 .. seealso::
708 :ref:`autogen_module_prefix`
710 :param process_revision_directives: a callable function that will
711 be passed a structure representing the end result of an autogenerate
712 or plain "revision" operation, which can be manipulated to affect
713 how the ``alembic revision`` command ultimately outputs new
714 revision scripts. The structure of the callable is::
716 def process_revision_directives(context, revision, directives):
717 pass
719 The ``directives`` parameter is a Python list containing
720 a single :class:`.MigrationScript` directive, which represents
721 the revision file to be generated. This list as well as its
722 contents may be freely modified to produce any set of commands.
723 The section :ref:`customizing_revision` shows an example of
724 doing this. The ``context`` parameter is the
725 :class:`.MigrationContext` in use,
726 and ``revision`` is a tuple of revision identifiers representing the
727 current revision of the database.
729 The callable is invoked at all times when the ``--autogenerate``
730 option is passed to ``alembic revision``. If ``--autogenerate``
731 is not passed, the callable is invoked only if the
732 ``revision_environment`` variable is set to True in the Alembic
733 configuration, in which case the given ``directives`` collection
734 will contain empty :class:`.UpgradeOps` and :class:`.DowngradeOps`
735 collections for ``.upgrade_ops`` and ``.downgrade_ops``. The
736 ``--autogenerate`` option itself can be inferred by inspecting
737 ``context.config.cmd_opts.autogenerate``.
739 The callable function may optionally be an instance of
740 a :class:`.Rewriter` object. This is a helper object that
741 assists in the production of autogenerate-stream rewriter functions.
744 .. versionadded:: 0.8.0
746 .. versionchanged:: 0.8.1 - The
747 :paramref:`.EnvironmentContext.configure.process_revision_directives`
748 hook can append op directives into :class:`.UpgradeOps` and
749 :class:`.DowngradeOps` which will be rendered in Python regardless
750 of whether the ``--autogenerate`` option is in use or not;
751 the ``revision_environment`` configuration variable should be
752 set to "true" in the config to enable this.
755 .. seealso::
757 :ref:`customizing_revision`
759 :ref:`autogen_rewriter`
761 :paramref:`.command.revision.process_revision_directives`
763 Parameters specific to individual backends:
765 :param mssql_batch_separator: The "batch separator" which will
766 be placed between each statement when generating offline SQL Server
767 migrations. Defaults to ``GO``. Note this is in addition to the
768 customary semicolon ``;`` at the end of each statement; SQL Server
769 considers the "batch separator" to denote the end of an
770 individual statement execution, and cannot group certain
771 dependent operations in one step.
772 :param oracle_batch_separator: The "batch separator" which will
773 be placed between each statement when generating offline
774 Oracle migrations. Defaults to ``/``. Oracle doesn't add a
775 semicolon between statements like most other backends.
777 """
778 opts = self.context_opts
779 if transactional_ddl is not None:
780 opts["transactional_ddl"] = transactional_ddl
781 if output_buffer is not None:
782 opts["output_buffer"] = output_buffer
783 elif self.config.output_buffer is not None:
784 opts["output_buffer"] = self.config.output_buffer
785 if starting_rev:
786 opts["starting_rev"] = starting_rev
787 if tag:
788 opts["tag"] = tag
789 if template_args and "template_args" in opts:
790 opts["template_args"].update(template_args)
791 opts["transaction_per_migration"] = transaction_per_migration
792 opts["target_metadata"] = target_metadata
793 opts["include_symbol"] = include_symbol
794 opts["include_object"] = include_object
795 opts["include_schemas"] = include_schemas
796 opts["render_as_batch"] = render_as_batch
797 opts["upgrade_token"] = upgrade_token
798 opts["downgrade_token"] = downgrade_token
799 opts["sqlalchemy_module_prefix"] = sqlalchemy_module_prefix
800 opts["alembic_module_prefix"] = alembic_module_prefix
801 opts["user_module_prefix"] = user_module_prefix
802 opts["literal_binds"] = literal_binds
803 opts["process_revision_directives"] = process_revision_directives
804 opts["on_version_apply"] = util.to_tuple(on_version_apply, default=())
806 if render_item is not None:
807 opts["render_item"] = render_item
808 if compare_type is not None:
809 opts["compare_type"] = compare_type
810 if compare_server_default is not None:
811 opts["compare_server_default"] = compare_server_default
812 opts["script"] = self.script
814 opts.update(kw)
816 self._migration_context = MigrationContext.configure(
817 connection=connection,
818 url=url,
819 dialect_name=dialect_name,
820 environment_context=self,
821 dialect_opts=dialect_opts,
822 opts=opts,
823 )
825 def run_migrations(self, **kw):
826 """Run migrations as determined by the current command line
827 configuration
828 as well as versioning information present (or not) in the current
829 database connection (if one is present).
831 The function accepts optional ``**kw`` arguments. If these are
832 passed, they are sent directly to the ``upgrade()`` and
833 ``downgrade()``
834 functions within each target revision file. By modifying the
835 ``script.py.mako`` file so that the ``upgrade()`` and ``downgrade()``
836 functions accept arguments, parameters can be passed here so that
837 contextual information, usually information to identify a particular
838 database in use, can be passed from a custom ``env.py`` script
839 to the migration functions.
841 This function requires that a :class:`.MigrationContext` has
842 first been made available via :meth:`.configure`.
844 """
845 with Operations.context(self._migration_context):
846 self.get_context().run_migrations(**kw)
848 def execute(self, sql, execution_options=None):
849 """Execute the given SQL using the current change context.
851 The behavior of :meth:`.execute` is the same
852 as that of :meth:`.Operations.execute`. Please see that
853 function's documentation for full detail including
854 caveats and limitations.
856 This function requires that a :class:`.MigrationContext` has
857 first been made available via :meth:`.configure`.
859 """
860 self.get_context().execute(sql, execution_options=execution_options)
862 def static_output(self, text):
863 """Emit text directly to the "offline" SQL stream.
865 Typically this is for emitting comments that
866 start with --. The statement is not treated
867 as a SQL execution, no ; or batch separator
868 is added, etc.
870 """
871 self.get_context().impl.static_output(text)
873 def begin_transaction(self):
874 """Return a context manager that will
875 enclose an operation within a "transaction",
876 as defined by the environment's offline
877 and transactional DDL settings.
879 e.g.::
881 with context.begin_transaction():
882 context.run_migrations()
884 :meth:`.begin_transaction` is intended to
885 "do the right thing" regardless of
886 calling context:
888 * If :meth:`.is_transactional_ddl` is ``False``,
889 returns a "do nothing" context manager
890 which otherwise produces no transactional
891 state or directives.
892 * If :meth:`.is_offline_mode` is ``True``,
893 returns a context manager that will
894 invoke the :meth:`.DefaultImpl.emit_begin`
895 and :meth:`.DefaultImpl.emit_commit`
896 methods, which will produce the string
897 directives ``BEGIN`` and ``COMMIT`` on
898 the output stream, as rendered by the
899 target backend (e.g. SQL Server would
900 emit ``BEGIN TRANSACTION``).
901 * Otherwise, calls :meth:`sqlalchemy.engine.Connection.begin`
902 on the current online connection, which
903 returns a :class:`sqlalchemy.engine.Transaction`
904 object. This object demarcates a real
905 transaction and is itself a context manager,
906 which will roll back if an exception
907 is raised.
909 Note that a custom ``env.py`` script which
910 has more specific transactional needs can of course
911 manipulate the :class:`~sqlalchemy.engine.Connection`
912 directly to produce transactional state in "online"
913 mode.
915 """
917 return self.get_context().begin_transaction()
919 def get_context(self):
920 """Return the current :class:`.MigrationContext` object.
922 If :meth:`.EnvironmentContext.configure` has not been
923 called yet, raises an exception.
925 """
927 if self._migration_context is None:
928 raise Exception("No context has been configured yet.")
929 return self._migration_context
931 def get_bind(self):
932 """Return the current 'bind'.
934 In "online" mode, this is the
935 :class:`sqlalchemy.engine.Connection` currently being used
936 to emit SQL to the database.
938 This function requires that a :class:`.MigrationContext`
939 has first been made available via :meth:`.configure`.
941 """
942 return self.get_context().bind
944 def get_impl(self):
945 return self.get_context().impl