summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2014-07-14 21:11:16 -0400
committerMike Bayer <mike_mp@zzzcomputing.com>2014-07-14 21:11:51 -0400
commitdbc8bbfba3591d2ea704673d90e95014765d0f10 (patch)
tree274df91b7f0217d8bff7b8d9f3e6e4d6bd6365a0
parentd2193f53c10d29a7a9b1846ebf322fbced55041f (diff)
downloadsqlalchemy-dbc8bbfba3591d2ea704673d90e95014765d0f10.tar.gz
- allow the compilation rule that gets the formatted name
to again have the chance to veto rendering, as the naming convention can make the decision that the name is "none" or not now.
-rw-r--r--lib/sqlalchemy/sql/compiler.py32
-rw-r--r--lib/sqlalchemy/sql/elements.py4
-rw-r--r--lib/sqlalchemy/sql/naming.py2
-rw-r--r--test/sql/test_metadata.py19
4 files changed, 43 insertions, 14 deletions
diff --git a/lib/sqlalchemy/sql/compiler.py b/lib/sqlalchemy/sql/compiler.py
index 99b74b3c8..da810e9fe 100644
--- a/lib/sqlalchemy/sql/compiler.py
+++ b/lib/sqlalchemy/sql/compiler.py
@@ -2537,8 +2537,9 @@ class DDLCompiler(Compiled):
def visit_check_constraint(self, constraint):
text = ""
if constraint.name is not None:
- text += "CONSTRAINT %s " % \
- self.preparer.format_constraint(constraint)
+ formatted_name = self.preparer.format_constraint(constraint)
+ if formatted_name is not None:
+ text += "CONSTRAINT %s " % formatted_name
text += "CHECK (%s)" % self.sql_compiler.process(constraint.sqltext,
include_table=False,
literal_binds=True)
@@ -2548,8 +2549,9 @@ class DDLCompiler(Compiled):
def visit_column_check_constraint(self, constraint):
text = ""
if constraint.name is not None:
- text += "CONSTRAINT %s " % \
- self.preparer.format_constraint(constraint)
+ formatted_name = self.preparer.format_constraint(constraint)
+ if formatted_name is not None:
+ text += "CONSTRAINT %s " % formatted_name
text += "CHECK (%s)" % constraint.sqltext
text += self.define_constraint_deferrability(constraint)
return text
@@ -2559,8 +2561,9 @@ class DDLCompiler(Compiled):
return ''
text = ""
if constraint.name is not None:
- text += "CONSTRAINT %s " % \
- self.preparer.format_constraint(constraint)
+ formatted_name = self.preparer.format_constraint(constraint)
+ if formatted_name is not None:
+ text += "CONSTRAINT %s " % formatted_name
text += "PRIMARY KEY "
text += "(%s)" % ', '.join(self.preparer.quote(c.name)
for c in constraint)
@@ -2571,14 +2574,15 @@ class DDLCompiler(Compiled):
preparer = self.dialect.identifier_preparer
text = ""
if constraint.name is not None:
- text += "CONSTRAINT %s " % \
- preparer.format_constraint(constraint)
+ formatted_name = self.preparer.format_constraint(constraint)
+ if formatted_name is not None:
+ text += "CONSTRAINT %s " % formatted_name
remote_table = list(constraint._elements.values())[0].column.table
text += "FOREIGN KEY(%s) REFERENCES %s (%s)" % (
', '.join(preparer.quote(f.parent.name)
for f in constraint._elements.values()),
self.define_constraint_remote_table(
- constraint, remote_table, preparer),
+ constraint, remote_table, preparer),
', '.join(preparer.quote(f.column.name)
for f in constraint._elements.values())
)
@@ -2597,11 +2601,11 @@ class DDLCompiler(Compiled):
return ''
text = ""
if constraint.name is not None:
- text += "CONSTRAINT %s " % \
- self.preparer.format_constraint(constraint)
+ formatted_name = self.preparer.format_constraint(constraint)
+ text += "CONSTRAINT %s " % formatted_name
text += "UNIQUE (%s)" % (
- ', '.join(self.preparer.quote(c.name)
- for c in constraint))
+ ', '.join(self.preparer.quote(c.name)
+ for c in constraint))
text += self.define_constraint_deferrability(constraint)
return text
@@ -2909,6 +2913,8 @@ class IdentifierPreparer(object):
constraint, constraint.table)
if name:
return self.quote(name)
+ elif isinstance(constraint.name, elements._defer_none_name):
+ return None
return self.quote(constraint.name)
def format_table(self, table, use_schema=True, name=None):
diff --git a/lib/sqlalchemy/sql/elements.py b/lib/sqlalchemy/sql/elements.py
index d273d9881..1447787ce 100644
--- a/lib/sqlalchemy/sql/elements.py
+++ b/lib/sqlalchemy/sql/elements.py
@@ -3209,7 +3209,7 @@ class _defer_name(_truncated_label):
"""
def __new__(cls, value):
if value is None:
- return _defer_none_name('_unnamed_')
+ return _NONE_NAME
else:
return super(_defer_name, cls).__new__(cls, value)
@@ -3217,6 +3217,8 @@ class _defer_name(_truncated_label):
class _defer_none_name(_defer_name):
"""indicate a 'deferred' name that was ultimately the value None."""
+_NONE_NAME = _defer_none_name("_unnamed_")
+
# for backwards compatibility in case
# someone is re-implementing the
# _truncated_identifier() sequence in a custom
diff --git a/lib/sqlalchemy/sql/naming.py b/lib/sqlalchemy/sql/naming.py
index bb838c542..eb017eb25 100644
--- a/lib/sqlalchemy/sql/naming.py
+++ b/lib/sqlalchemy/sql/naming.py
@@ -155,6 +155,8 @@ def _constraint_name_for_table(const, table):
convention % ConventionDict(const, table,
metadata.naming_convention)
)
+ elif isinstance(convention, _defer_none_name):
+ return None
@event.listens_for(Constraint, "after_parent_attach")
@event.listens_for(Index, "after_parent_attach")
diff --git a/test/sql/test_metadata.py b/test/sql/test_metadata.py
index 7aa2059dc..ee7d372d7 100644
--- a/test/sql/test_metadata.py
+++ b/test/sql/test_metadata.py
@@ -3013,6 +3013,25 @@ class NamingConventionTest(fixtures.TestBase, AssertsCompiledSQL):
schema.CreateTable(u1).compile
)
+ def test_schematype_no_ck_name_boolean_no_name(self):
+ m1 = MetaData() # no naming convention
+
+ u1 = Table(
+ 'user', m1,
+ Column('x', Boolean())
+ )
+ # constraint gets special _defer_none_name
+ eq_(
+ [c for c in u1.constraints
+ if isinstance(c, CheckConstraint)][0].name, "_unnamed_"
+ )
+
+ self.assert_compile(
+ schema.CreateTable(u1),
+ "CREATE TABLE user (x BOOLEAN, CHECK (x IN (0, 1)))"
+ )
+
+
def test_ck_constraint_redundant_event(self):
u1 = self._fixture(naming_convention={
"ck": "ck_%(table_name)s_%(constraint_name)s"})