diff options
author | Mike Bayer <mike_mp@zzzcomputing.com> | 2014-07-14 21:11:16 -0400 |
---|---|---|
committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2014-07-14 21:11:51 -0400 |
commit | dbc8bbfba3591d2ea704673d90e95014765d0f10 (patch) | |
tree | 274df91b7f0217d8bff7b8d9f3e6e4d6bd6365a0 | |
parent | d2193f53c10d29a7a9b1846ebf322fbced55041f (diff) | |
download | sqlalchemy-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.py | 32 | ||||
-rw-r--r-- | lib/sqlalchemy/sql/elements.py | 4 | ||||
-rw-r--r-- | lib/sqlalchemy/sql/naming.py | 2 | ||||
-rw-r--r-- | test/sql/test_metadata.py | 19 |
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"}) |