return self
+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 _defer_name(_truncated_label):
"""mark a name as 'deferred' for the purposes of automated name
generation.
def __new__(cls, value):
if value is None:
return _NONE_NAME
+ elif isinstance(value, conv):
+ return value
else:
return super(_defer_name, cls).__new__(cls, value)
UniqueConstraint, CheckConstraint, Index, Table, Column
from .. import event, events
from .. import exc
-from .elements import _truncated_label, _defer_name, _defer_none_name
+from .elements import _truncated_label, _defer_name, _defer_none_name, conv
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):
def _constraint_name_for_table(const, table):
metadata = table.metadata
convention = _get_convention(metadata.naming_convention, type(const))
- if convention is not None and (
+
+ if isinstance(const.name, conv):
+ return const.name
+ elif convention is not None and (
const.name is None or not isinstance(const.name, conv) and
"constraint_name" in convention
):
class NamingConventionTest(fixtures.TestBase, AssertsCompiledSQL):
- dialect = 'default'
+ __dialect__ = 'default'
def _fixture(self, naming_convention, table_schema=None):
m1 = MetaData(naming_convention=naming_convention)
# but is hit at compile time
self.assert_compile(
schema.CreateTable(u1),
- "CREATE TABLE user ("
+ 'CREATE TABLE "user" ('
"x BOOLEAN, "
"CONSTRAINT ck_user_foo CHECK (x IN (0, 1))"
")"
# but is hit at compile time
self.assert_compile(
schema.CreateTable(u1),
- "CREATE TABLE user ("
+ 'CREATE TABLE "user" ('
"x VARCHAR(1), "
"CONSTRAINT ck_user_foo CHECK (x IN ('a', 'b'))"
")"
)
+ def test_schematype_ck_name_propagate_conv(self):
+ m1 = MetaData(naming_convention={
+ "ck": "ck_%(table_name)s_%(constraint_name)s"})
+
+ u1 = Table('user', m1,
+ Column('x', Enum('a', 'b', name=naming.conv('foo')))
+ )
+ eq_(
+ [c for c in u1.constraints
+ if isinstance(c, CheckConstraint)][0].name, "foo"
+ )
+ # but is hit at compile time
+ self.assert_compile(
+ schema.CreateTable(u1),
+ 'CREATE TABLE "user" ('
+ "x VARCHAR(1), "
+ "CONSTRAINT foo CHECK (x IN ('a', 'b'))"
+ ")"
+ )
+
def test_schematype_ck_name_boolean_no_name(self):
m1 = MetaData(naming_convention={
"ck": "ck_%(table_name)s_%(constraint_name)s"
self.assert_compile(
schema.CreateTable(u1),
- "CREATE TABLE user (x BOOLEAN, CHECK (x IN (0, 1)))"
+ 'CREATE TABLE "user" (x BOOLEAN, CHECK (x IN (0, 1)))'
)