diff options
Diffstat (limited to 'lib/sqlalchemy/sql')
-rw-r--r-- | lib/sqlalchemy/sql/compiler.py | 32 | ||||
-rw-r--r-- | lib/sqlalchemy/sql/util.py | 20 |
2 files changed, 31 insertions, 21 deletions
diff --git a/lib/sqlalchemy/sql/compiler.py b/lib/sqlalchemy/sql/compiler.py index 6802bfbef..a41a149d1 100644 --- a/lib/sqlalchemy/sql/compiler.py +++ b/lib/sqlalchemy/sql/compiler.py @@ -922,6 +922,11 @@ class SQLCompiler(engine.Compiled): class DDLCompiler(engine.Compiled): + + @util.memoized_property + def sql_compiler(self): + return self.dialect.statement_compiler(self.dialect, self.statement) + @property def preparer(self): return self.dialect.identifier_preparer @@ -982,7 +987,9 @@ class DDLCompiler(engine.Compiled): const = ", \n\t".join(p for p in (self.process(constraint) for constraint in table.constraints if constraint is not table.primary_key - and constraint.inline_ddl + and ( + constraint._create_rule is None or + constraint._create_rule(self)) and ( not self.dialect.supports_alter or not getattr(constraint, 'use_alter', False) @@ -1058,13 +1065,6 @@ class DDLCompiler(engine.Compiled): def post_create_table(self, table): return '' - def _compile(self, tocompile, parameters): - """compile the given string/parameters using this SchemaGenerator's dialect.""" - - compiler = self.dialect.statement_compiler(self.dialect, tocompile, parameters) - compiler.compile() - return compiler - def _validate_identifier(self, ident, truncate): if truncate: if len(ident) > self.dialect.max_identifier_length: @@ -1082,7 +1082,7 @@ class DDLCompiler(engine.Compiled): if isinstance(column.server_default.arg, basestring): return "'%s'" % column.server_default.arg else: - return unicode(self._compile(column.server_default.arg, None)) + return self.sql_compiler.process(column.server_default.arg) else: return None @@ -1091,7 +1091,8 @@ class DDLCompiler(engine.Compiled): if constraint.name is not None: text += "CONSTRAINT %s " % \ self.preparer.format_constraint(constraint) - text += " CHECK (%s)" % constraint.sqltext + sqltext = sql_util.expression_as_ddl(constraint.sqltext) + text += "CHECK (%s)" % self.sql_compiler.process(sqltext) text += self.define_constraint_deferrability(constraint) return text @@ -1138,17 +1139,6 @@ class DDLCompiler(engine.Compiled): text += self.define_constraint_deferrability(constraint) return text - def visit_enum_constraint(self, constraint): - text = "" - if constraint.name is not None: - text += "CONSTRAINT %s " % \ - self.preparer.format_constraint(constraint) - text += " CHECK (%s IN (%s))" % ( - self.preparer.format_column(constraint.column), - ",".join("'%s'" % x for x in constraint.type.enums) - ) - return text - def define_constraint_cascades(self, constraint): text = "" if constraint.ondelete is not None: diff --git a/lib/sqlalchemy/sql/util.py b/lib/sqlalchemy/sql/util.py index a84a3eb74..78160ad1e 100644 --- a/lib/sqlalchemy/sql/util.py +++ b/lib/sqlalchemy/sql/util.py @@ -79,6 +79,26 @@ def find_columns(clause): visitors.traverse(clause, {}, {'column':cols.add}) return cols +def expression_as_ddl(clause): + """Given a SQL expression, convert for usage in DDL, such as + CREATE INDEX and CHECK CONSTRAINT. + + Converts bind params into quoted literals, column identifiers + into detached column constructs so that the parent table + identifier is not included. + + """ + def repl(element): + if isinstance(element, expression._BindParamClause): + return expression.literal_column(repr(element.value)) + elif isinstance(element, expression.ColumnClause) and \ + element.table is not None: + return expression.column(element.name) + else: + return None + + return visitors.replacement_traverse(clause, {}, repl) + def adapt_criterion_to_null(crit, nulls): """given criterion containing bind params, convert selected elements to IS NULL.""" |