summaryrefslogtreecommitdiff
path: root/alembic
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2011-11-28 15:50:14 -0500
committerMike Bayer <mike_mp@zzzcomputing.com>2011-11-28 15:50:14 -0500
commit73ff4327d5c47f8e0480de4bc9f520c4338a63da (patch)
treed46e70ce9b229aaba74f377d173f6f05503416a6 /alembic
parent5d475742ee412e2c6fb261d935cf0e947c21a063 (diff)
downloadalembic-73ff4327d5c47f8e0480de4bc9f520c4338a63da.tar.gz
- rename autogenerate_metadata to target_metadata, autogenerate_sqlalchemy_prefix
to sqlalchemy_module_prefix - add create_check_constraint() directive
Diffstat (limited to 'alembic')
-rw-r--r--alembic/autogenerate.py4
-rw-r--r--alembic/context.py36
-rw-r--r--alembic/op.py50
-rw-r--r--alembic/templates/generic/env.py6
-rw-r--r--alembic/templates/multidb/env.py6
-rw-r--r--alembic/templates/pylons/env.py6
6 files changed, 86 insertions, 22 deletions
diff --git a/alembic/autogenerate.py b/alembic/autogenerate.py
index b6811fa..bae14af 100644
--- a/alembic/autogenerate.py
+++ b/alembic/autogenerate.py
@@ -14,7 +14,7 @@ log = logging.getLogger(__name__)
# top level
def produce_migration_diffs(template_args, imports):
- metadata = _context_opts['autogenerate_metadata']
+ metadata = _context_opts['target_metadata']
if metadata is None:
raise util.CommandError(
"Can't proceed with --autogenerate option; environment "
@@ -347,7 +347,7 @@ def _modify_col(tname, cname,
return text
def _autogenerate_prefix():
- return _context_opts['autogenerate_sqlalchemy_prefix'] or ''
+ return _context_opts['sqlalchemy_module_prefix'] or ''
def _render_column(column, autogen_context):
opts = []
diff --git a/alembic/context.py b/alembic/context.py
index 0ac9cb9..51a060e 100644
--- a/alembic/context.py
+++ b/alembic/context.py
@@ -309,12 +309,12 @@ def configure(
output_buffer=None,
starting_rev=None,
tag=None,
- autogenerate_metadata=None,
+ target_metadata=None,
compare_type=False,
compare_server_default=False,
upgrade_token="upgrades",
downgrade_token="downgrades",
- autogenerate_sqlalchemy_prefix="sa.",
+ sqlalchemy_module_prefix="sa.",
):
"""Configure the migration environment.
@@ -351,11 +351,12 @@ def configure(
``--sql`` mode.
:param tag: a string tag for usage by custom ``env.py`` scripts. Set via
the ``--tag`` option, can be overridden here.
- :param autogenerate_metadata: a :class:`sqlalchemy.schema.MetaData` object that
+ :param target_metadata: a :class:`sqlalchemy.schema.MetaData` object that
will be consulted if the ``--autogenerate`` option is passed to the
"alembic revision" command. The tables present will be compared against
what is locally available on the target :class:`~sqlalchemy.engine.base.Connection`
to produce candidate upgrade/downgrade operations.
+
:param compare_type: Indicates type comparison behavior during an autogenerate
operation. Defaults to ``False`` which disables type comparison. Set to
``True`` to turn on default type comparison, which has varied accuracy depending
@@ -371,7 +372,12 @@ def configure(
# False if not, or None to allow the default implementation
# to compare these types
pass
-
+
+ ``inspected_column`` is a dictionary structure as returned by
+ :meth:`sqlalchemy.engine.reflection.Inspector.get_columns`, whereas
+ ``metadata_column`` is a :class:`sqlalchemy.schema.Column` from
+ the local model environment.
+
A return value of ``None`` indicates to allow default type comparison to
proceed.
@@ -392,19 +398,29 @@ def configure(
# to compare these defaults
pass
+ ``inspected_column`` is a dictionary structure as returned by
+ :meth:`sqlalchemy.engine.reflection.Inspector.get_columns`, whereas
+ ``metadata_column`` is a :class:`sqlalchemy.schema.Column` from
+ the local model environment.
+
A return value of ``None`` indicates to allow default server default comparison
to proceed. Note that some backends such as Postgresql actually execute
the two defaults on the database side to compare for equivalence.
:param upgrade_token: when running "alembic revision" with the ``--autogenerate``
option, the text of the candidate upgrade operations will be present in this
- template variable when script.py.mako is rendered.
+ template variable when ``script.py.mako`` is rendered. Defaults to ``upgrades``.
:param downgrade_token: when running "alembic revision" with the ``--autogenerate``
option, the text of the candidate downgrade operations will be present in this
- template variable when script.py.mako is rendered.
- :param autogenerate_sqlalchemy_prefix: When autogenerate refers to SQLAlchemy
+ template variable when ``script.py.mako`` is rendered. Defaults to ``downgrades``.
+
+ :param sqlalchemy_module_prefix: When autogenerate refers to SQLAlchemy
:class:`~sqlalchemy.schema.Column` or type classes, this prefix will be used
- (i.e. ``sa.Column("somename", sa.Integer)``)
+ (i.e. ``sa.Column("somename", sa.Integer)``) Defaults to "``sa.``".
+ Can be ``None`` to indicate no prefix.
+ Note that when dialect-specific types are rendered, autogenerate
+ will render them using the dialect module name, i.e. ``mssql.BIT()``,
+ ``postgresql.UUID()``.
"""
@@ -431,10 +447,10 @@ def configure(
opts['starting_rev'] = starting_rev
if tag:
opts['tag'] = tag
- opts['autogenerate_metadata'] = autogenerate_metadata
+ opts['target_metadata'] = target_metadata
opts['upgrade_token'] = upgrade_token
opts['downgrade_token'] = downgrade_token
- opts['autogenerate_sqlalchemy_prefix'] = autogenerate_sqlalchemy_prefix
+ opts['sqlalchemy_module_prefix'] = sqlalchemy_module_prefix
_context = Context(
dialect, _script, connection,
opts['fn'],
diff --git a/alembic/op.py b/alembic/op.py
index 227dc9c..848e40b 100644
--- a/alembic/op.py
+++ b/alembic/op.py
@@ -1,7 +1,7 @@
from alembic import util
from alembic.ddl import impl
from alembic.context import get_impl, get_context
-from sqlalchemy.types import NULLTYPE
+from sqlalchemy.types import NULLTYPE, Integer
from sqlalchemy import schema, sql
__all__ = sorted([
@@ -18,6 +18,7 @@ __all__ = sorted([
'bulk_insert',
'rename_table',
'create_unique_constraint',
+ 'create_check_constraint',
'get_context',
'get_bind',
'execute'])
@@ -47,6 +48,13 @@ def _unique_constraint(name, source, local_cols, **kw):
t.append_constraint(uq)
return uq
+def _check_constraint(name, source, condition, **kw):
+ t = schema.Table(source, schema.MetaData(),
+ schema.Column('x', Integer))
+ ck = schema.CheckConstraint(condition, name=name, **kw)
+ t.append_constraint(ck)
+ return ck
+
def _table(name, *columns, **kw):
m = schema.MetaData()
t = schema.Table(name, m, *columns, **kw)
@@ -336,6 +344,46 @@ def create_unique_constraint(name, source, local_cols, **kw):
**kw)
)
+def create_check_constraint(name, source, condition, **kw):
+ """Issue a "create check constraint" instruction using the current change context.
+
+ e.g.::
+
+ from alembic.op import create_check_constraint
+ from sqlalchemy.sql import column, func
+
+ create_check_constraint(
+ "ck_user_name_len",
+ "user",
+ func.len(column('name')) > 5
+ )
+
+ CHECK constraints are usually against a SQL expression, so ad-hoc
+ table metadata is usually needed. The function will convert the given
+ arguments into a :class:`sqlalchemy.schema.CheckConstraint` bound
+ to an anonymous table in order to emit the CREATE statement.
+
+ :param name: Name of the check constraint. The name is necessary
+ so that an ALTER statement can be emitted. For setups that
+ use an automated naming scheme such as that described at
+ `NamingConventions <http://www.sqlalchemy.org/trac/wiki/UsageRecipes/NamingConventions>`_,
+ ``name`` here can be ``None``, as the event listener will
+ apply the name to the constraint object when it is associated
+ with the table.
+ :param source: String name of the source table. Currently
+ there is no support for dotted schema names.
+ :param condition: SQL expression that's the condition of the constraint.
+ Can be a string or SQLAlchemy expression language structure.
+ :param deferrable: optional bool. If set, emit DEFERRABLE or NOT DEFERRABLE when
+ issuing DDL for this constraint.
+ :param initially: optional string. If set, emit INITIALLY <value> when issuing DDL
+ for this constraint.
+
+ """
+ get_impl().add_constraint(
+ _check_constraint(name, source, condition, **kw)
+ )
+
def create_table(name, *columns, **kw):
"""Issue a "create table" instruction using the current change context.
diff --git a/alembic/templates/generic/env.py b/alembic/templates/generic/env.py
index 5095f0b..4bc6065 100644
--- a/alembic/templates/generic/env.py
+++ b/alembic/templates/generic/env.py
@@ -13,8 +13,8 @@ fileConfig(config.config_file_name)
# add your model's MetaData object here
# for 'autogenerate' support
# from myapp import mymodel
-# autogenerate_metadata = mymodel.Base.metadata
-autogenerate_metadata = None
+# target_metadata = mymodel.Base.metadata
+target_metadata = None
# other values from the config, defined by the needs of env.py,
# can be acquired:
@@ -55,7 +55,7 @@ def run_migrations_online():
connection = engine.connect()
context.configure(
connection=connection,
- autogenerate_metadata=autogenerate_metadata
+ target_metadata=target_metadata
)
trans = connection.begin()
diff --git a/alembic/templates/multidb/env.py b/alembic/templates/multidb/env.py
index 1ace59c..0db2a67 100644
--- a/alembic/templates/multidb/env.py
+++ b/alembic/templates/multidb/env.py
@@ -20,11 +20,11 @@ db_names = options.get_main_option('databases')
# helpful here in case a "copy" of
# a MetaData is needed.
# from myapp import mymodel
-# autogenerate_metadata = {
+# target_metadata = {
# 'engine1':mymodel.metadata1,
# 'engine2':mymodel.metadata2
#}
-autogenerate_metadata = {}
+target_metadata = {}
def run_migrations_offline():
"""Run migrations in 'offline' mode.
@@ -87,7 +87,7 @@ def run_migrations_online():
connection=rec['connection'],
upgrade_token="%s_upgrades",
downgrade_token="%s_downgrades",
- autogenerate_metadata=autogenerate_metadata.get(name)
+ target_metadata=target_metadata.get(name)
)
context.execute("--running migrations for engine %s" % name)
context.run_migrations(engine=name)
diff --git a/alembic/templates/pylons/env.py b/alembic/templates/pylons/env.py
index da193f4..e9ea402 100644
--- a/alembic/templates/pylons/env.py
+++ b/alembic/templates/pylons/env.py
@@ -26,8 +26,8 @@ meta = __import__("%s.model.meta" % config['pylons.package']).model.meta
# add your model's MetaData object here
# for 'autogenerate' support
# from myapp import mymodel
-# autogenerate_metadata = mymodel.Base.metadata
-autogenerate_metadata = None
+# target_metadata = mymodel.Base.metadata
+target_metadata = None
def run_migrations_offline():
"""Run migrations in 'offline' mode.
@@ -55,7 +55,7 @@ def run_migrations_online():
connection = meta.engine.connect()
context.configure(
connection=connection,
- autogenerate_metadata=autogenerate_metadata
+ target_metadata=target_metadata
)
trans = connection.begin()
try: