summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/sql/naming.py
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2014-03-12 17:33:03 -0400
committerMike Bayer <mike_mp@zzzcomputing.com>2014-03-12 17:33:03 -0400
commit36792434c74dea43a0f10f5fe1cc45c4206f01ee (patch)
tree792749694902e82ef088d481fca7a1fa70f7410f /lib/sqlalchemy/sql/naming.py
parenta7ef7eccaacae5341bb03a58cc0538718c33c329 (diff)
downloadsqlalchemy-36792434c74dea43a0f10f5fe1cc45c4206f01ee.tar.gz
- Added a new feature :func:`.schema.conv`, the purpose of which is to
mark a constraint name as already having had a naming convention applied. This token will be used by Alembic migrations as of Alembic 0.6.4 in order to render constraints in migration scripts with names marked as already having been subject to a naming convention. re: #2991
Diffstat (limited to 'lib/sqlalchemy/sql/naming.py')
-rw-r--r--lib/sqlalchemy/sql/naming.py50
1 files changed, 45 insertions, 5 deletions
diff --git a/lib/sqlalchemy/sql/naming.py b/lib/sqlalchemy/sql/naming.py
index 3ba7f5105..1c5fae193 100644
--- a/lib/sqlalchemy/sql/naming.py
+++ b/lib/sqlalchemy/sql/naming.py
@@ -16,13 +16,54 @@ from .. import exc
from .elements import _truncated_label
import re
+class conv(_truncated_label):
+ """Mark a string indicating that a name has already been converted
+ by a naming convention.
+
+ This is a string subclass that indicates a name that should not be
+ subject to any further naming conventions.
+
+ E.g. when we create a :class:`.Constraint` using a naming convention
+ as follows::
+
+ m = MetaData(naming_convention={"ck": "ck_%(table_name)s_%(constraint_name)s"})
+ t = Table('t', m, Column('x', Integer),
+ CheckConstraint('x > 5', name='x5'))
+
+ The name of the above constraint will be rendered as ``"ck_t_x5"``. That is,
+ the existing name ``x5`` is used in the naming convention as the ``constraint_name``
+ token.
+
+ In some situations, such as in migration scripts, we may be rendering
+ the above :class:`.CheckConstraint` with a name that's already been
+ converted. In order to make sure the name isn't double-modified, the
+ new name is applied using the :func:`.schema.conv` marker. We can
+ use this explicitly as follows::
+
+
+ m = MetaData(naming_convention={"ck": "ck_%(table_name)s_%(constraint_name)s"})
+ t = Table('t', m, Column('x', Integer),
+ CheckConstraint('x > 5', name=conv('ck_t_x5')))
+
+ Where above, the :func:`.schema.conv` marker indicates that the constraint
+ name here is final, and the name will render as ``"ck_t_x5"`` and not
+ ``"ck_t_ck_t_x5"``
+
+ .. versionadded:: 0.9.4
+
+ .. seealso::
+
+ :ref:`constraint_naming_conventions`
+
+ """
+
class ConventionDict(object):
def __init__(self, const, table, convention):
self.const = const
self._is_fk = isinstance(const, ForeignKeyConstraint)
self.table = table
self.convention = convention
- self._const_name = const._orig_name = getattr(const, '_orig_name', const.name)
+ self._const_name = const.name
def _key_table_name(self):
return self.table.name
@@ -41,9 +82,8 @@ class ConventionDict(object):
"%(constraint_name)s token requires that "
"constraint is explicitly named."
)
- # they asked for a name that's derived from the existing
- # name, so set the existing name to None
- self.const.name = None
+ if not isinstance(self._const_name, conv):
+ self.const.name = None
return self._const_name
def _key_column_X_name(self, idx):
@@ -118,7 +158,7 @@ def _constraint_name(const, table):
metadata = table.metadata
convention = _get_convention(metadata.naming_convention, type(const))
if convention is not None:
- newname = _truncated_label(
+ newname = conv(
convention % ConventionDict(const, table, metadata.naming_convention)
)
if const.name is None: