From 9f894d2f265bb5fd03ab0b3aa3fd164108c99259 Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Wed, 5 Nov 2008 20:50:48 +0000 Subject: - Dialects can now generate label names of adjustable length. Pass in the argument "label_length=" to create_engine() to adjust how many characters max will be present in dynamically generated column labels, i.e. "somecolumn AS somelabel". Any value less than 6 will result in a label of minimal size, consiting of an underscore and a numeric counter. The compiler uses the value of dialect.max_identifier_length as a default. [ticket:1211] - removed ANON_NAME regular expression, using string patterns now - _generated_label() unicode subclass is used to indicate generated names which are subject to truncation --- lib/sqlalchemy/sql/compiler.py | 83 +++++++++++++++++++++--------------------- 1 file changed, 42 insertions(+), 41 deletions(-) (limited to 'lib/sqlalchemy/sql/compiler.py') diff --git a/lib/sqlalchemy/sql/compiler.py b/lib/sqlalchemy/sql/compiler.py index 63557f24b..1c7c66f47 100644 --- a/lib/sqlalchemy/sql/compiler.py +++ b/lib/sqlalchemy/sql/compiler.py @@ -47,7 +47,6 @@ ILLEGAL_INITIAL_CHARACTERS = re.compile(r'[0-9$]') BIND_PARAMS = re.compile(r'(? self.dialect.max_identifier_length: - counter = self.generated_ids.get(ident_class, 1) - truncname = anonname[0:self.dialect.max_identifier_length - 6] + "_" + hex(counter)[2:] - self.generated_ids[ident_class] = counter + 1 + if len(anonname) > self.label_length: + counter = self.truncated_names.get(ident_class, 1) + truncname = anonname[0:max(self.label_length - 6, 0)] + "_" + hex(counter)[2:] + self.truncated_names[ident_class] = counter + 1 else: truncname = anonname - self.generated_ids[(ident_class, name)] = truncname + self.truncated_names[(ident_class, name)] = truncname return truncname - def _process_anon(self, match): - (ident, derived) = match.group(1, 2) - - key = ('anonymous', ident) - if key in self.generated_ids: - return self.generated_ids[key] - else: - anonymous_counter = self.generated_ids.get(('anon_counter', derived), 1) - newname = derived + "_" + str(anonymous_counter) - self.generated_ids[('anon_counter', derived)] = anonymous_counter + 1 - self.generated_ids[key] = newname - return newname - def _anonymize(self, name): - return ANONYMOUS_LABEL.sub(self._process_anon, name) + return name % self.anon_map + + def _process_anon(self, key): + (ident, derived) = key.split(' ') + + anonymous_counter = self.anon_map.get(derived, 1) + self.anon_map[derived] = anonymous_counter + 1 + return derived + "_" + str(anonymous_counter) def bindparam_string(self, name): if self.positional: @@ -438,7 +439,7 @@ class DefaultCompiler(engine.Compiled): def visit_alias(self, alias, asfrom=False, **kwargs): if asfrom: - return self.process(alias.original, asfrom=True, **kwargs) + " AS " + self.preparer.format_alias(alias, self._anonymize(alias.name)) + return self.process(alias.original, asfrom=True, **kwargs) + " AS " + self.preparer.format_alias(alias, alias.name % self.anon_map) else: return self.process(alias.original, **kwargs) @@ -457,7 +458,7 @@ class DefaultCompiler(engine.Compiled): not column.is_literal and \ column.table is not None and \ not isinstance(column.table, sql.Select): - return _CompileLabel(column, column.name) + return _CompileLabel(column, sql._generated_label(column.name)) elif not isinstance(column, (sql._UnaryExpression, sql._TextClause, sql._BindParamClause)) and (not hasattr(column, 'name') or isinstance(column, sql._Function)): return _CompileLabel(column, column.anon_label) else: -- cgit v1.2.1