diff options
author | Mike Bayer <mike_mp@zzzcomputing.com> | 2016-01-11 14:35:56 -0500 |
---|---|---|
committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2016-01-11 16:44:28 -0500 |
commit | 6fbfadc7388dad4576ad99ce597e0878ee1d297f (patch) | |
tree | 2aeaeec66050d6377ae719f825b6d5f45ea62252 /lib/sqlalchemy/sql | |
parent | b301f009e18246db9277a4b9d7e3a1bf01a92ae9 (diff) | |
download | sqlalchemy-6fbfadc7388dad4576ad99ce597e0878ee1d297f.tar.gz |
- reorganize schema_translate_map to be succinct and gain the performance
back by using an attrgetter for the default case
Diffstat (limited to 'lib/sqlalchemy/sql')
-rw-r--r-- | lib/sqlalchemy/sql/compiler.py | 37 | ||||
-rw-r--r-- | lib/sqlalchemy/sql/ddl.py | 8 | ||||
-rw-r--r-- | lib/sqlalchemy/sql/schema.py | 56 |
3 files changed, 68 insertions, 33 deletions
diff --git a/lib/sqlalchemy/sql/compiler.py b/lib/sqlalchemy/sql/compiler.py index 4068d18be..c4e73a1e3 100644 --- a/lib/sqlalchemy/sql/compiler.py +++ b/lib/sqlalchemy/sql/compiler.py @@ -183,6 +183,10 @@ class Compiled(object): .. versionadded:: 1.1 + .. seealso:: + + :ref:`schema_translating` + :param compile_kwargs: additional kwargs that will be passed to the initial call to :meth:`.Compiled.process`. @@ -661,12 +665,7 @@ class SQLCompiler(Compiled): if table is None or not include_table or not table.named_with_column: return name else: - - # inlining of preparer._get_effective_schema - effective_schema = table.schema - if self.preparer.schema_translate_map: - effective_schema = self.preparer.schema_translate_map.get( - effective_schema, effective_schema) + effective_schema = self.preparer.schema_for_object(table) if effective_schema: schema_prefix = self.preparer.quote_schema( @@ -1830,12 +1829,7 @@ class SQLCompiler(Compiled): def visit_table(self, table, asfrom=False, iscrud=False, ashint=False, fromhints=None, use_schema=True, **kwargs): if asfrom or ashint: - - # inlining of preparer._get_effective_schema - effective_schema = table.schema - if self.preparer.schema_translate_map: - effective_schema = self.preparer.schema_translate_map.get( - effective_schema, effective_schema) + effective_schema = self.preparer.schema_for_object(table) if use_schema and effective_schema: ret = self.preparer.quote_schema(effective_schema) + \ @@ -2289,7 +2283,7 @@ class DDLCompiler(Compiled): def _prepared_index_name(self, index, include_schema=False): if index.table is not None: - effective_schema = self.preparer._get_effective_schema(index.table) + effective_schema = self.preparer.schema_for_object(index.table) else: effective_schema = None if include_schema and effective_schema: @@ -2648,7 +2642,7 @@ class IdentifierPreparer(object): illegal_initial_characters = ILLEGAL_INITIAL_CHARACTERS - schema_translate_map = util.immutabledict() + schema_for_object = schema._schema_getter(None) def __init__(self, dialect, initial_quote='"', final_quote=None, escape_quote='"', omit_schema=False): @@ -2677,7 +2671,7 @@ class IdentifierPreparer(object): def _with_schema_translate(self, schema_translate_map): prep = self.__class__.__new__(self.__class__) prep.__dict__.update(self.__dict__) - prep.schema_translate_map = schema_translate_map + prep.schema_for_object = schema._schema_getter(schema_translate_map) return prep def _escape_identifier(self, value): @@ -2753,7 +2747,7 @@ class IdentifierPreparer(object): def format_sequence(self, sequence, use_schema=True): name = self.quote(sequence.name) - effective_schema = self._get_effective_schema(sequence) + effective_schema = self.schema_for_object(sequence) if (not self.omit_schema and use_schema and effective_schema is not None): @@ -2780,13 +2774,6 @@ class IdentifierPreparer(object): return None return self.quote(constraint.name) - def _get_effective_schema(self, table): - effective_schema = table.schema - if self.schema_translate_map: - effective_schema = self.schema_translate_map.get( - effective_schema, effective_schema) - return effective_schema - def format_table(self, table, use_schema=True, name=None): """Prepare a quoted table and schema name.""" @@ -2794,7 +2781,7 @@ class IdentifierPreparer(object): name = table.name result = self.quote(name) - effective_schema = self._get_effective_schema(table) + effective_schema = self.schema_for_object(table) if not self.omit_schema and use_schema \ and effective_schema: @@ -2837,7 +2824,7 @@ class IdentifierPreparer(object): # ('database', 'owner', etc.) could override this and return # a longer sequence. - effective_schema = self._get_effective_schema(table) + effective_schema = self.schema_for_object(table) if not self.omit_schema and use_schema and \ effective_schema: diff --git a/lib/sqlalchemy/sql/ddl.py b/lib/sqlalchemy/sql/ddl.py index 7225da551..7953b61b8 100644 --- a/lib/sqlalchemy/sql/ddl.py +++ b/lib/sqlalchemy/sql/ddl.py @@ -679,7 +679,7 @@ class SchemaGenerator(DDLBase): def _can_create_table(self, table): self.dialect.validate_identifier(table.name) - effective_schema = self.connection._get_effective_schema(table) + effective_schema = self.connection.schema_for_object(table) if effective_schema: self.dialect.validate_identifier(effective_schema) return not self.checkfirst or \ @@ -687,7 +687,7 @@ class SchemaGenerator(DDLBase): table.name, schema=effective_schema) def _can_create_sequence(self, sequence): - effective_schema = self.connection._get_effective_schema(sequence) + effective_schema = self.connection.schema_for_object(sequence) return self.dialect.supports_sequences and \ ( @@ -885,14 +885,14 @@ class SchemaDropper(DDLBase): def _can_drop_table(self, table): self.dialect.validate_identifier(table.name) - effective_schema = self.connection._get_effective_schema(table) + effective_schema = self.connection.schema_for_object(table) if effective_schema: self.dialect.validate_identifier(effective_schema) return not self.checkfirst or self.dialect.has_table( self.connection, table.name, schema=effective_schema) def _can_drop_sequence(self, sequence): - effective_schema = self.connection._get_effective_schema(sequence) + effective_schema = self.connection.schema_for_object(sequence) return self.dialect.supports_sequences and \ ((not self.dialect.sequences_optional or not sequence.optional) and diff --git a/lib/sqlalchemy/sql/schema.py b/lib/sqlalchemy/sql/schema.py index b244d746c..628d06183 100644 --- a/lib/sqlalchemy/sql/schema.py +++ b/lib/sqlalchemy/sql/schema.py @@ -30,20 +30,19 @@ as components in SQL expressions. """ from __future__ import absolute_import -import inspect from .. import exc, util, event, inspection from .base import SchemaEventTarget, DialectKWArgs +import operator from . import visitors from . import type_api from .base import _bind_or_error, ColumnCollection -from .elements import ClauseElement, ColumnClause, _truncated_label, \ +from .elements import ClauseElement, ColumnClause, \ _as_truncated, TextClause, _literal_as_text,\ - ColumnElement, _find_columns, quoted_name + ColumnElement, quoted_name from .selectable import TableClause import collections import sqlalchemy from . import ddl -import types RETAIN_SCHEMA = util.symbol('retain_schema') @@ -3862,3 +3861,52 @@ class ThreadLocalMetaData(MetaData): for e in self.__engines.values(): if hasattr(e, 'dispose'): e.dispose() + + +class _SchemaTranslateMap(object): + """Provide translation of schema names based on a mapping. + + Also provides helpers for producing cache keys and optimized + access when no mapping is present. + + Used by the :paramref:`.Connection.execution_options.schema_translate_map` + feature. + + .. versionadded:: 1.1 + + + """ + __slots__ = 'map_', '__call__', 'hash_key', 'is_default' + + _default_schema_getter = operator.attrgetter("schema") + + def __init__(self, map_): + self.map_ = map_ + if map_ is not None: + def schema_for_object(obj): + effective_schema = self._default_schema_getter(obj) + effective_schema = map_.get(effective_schema, effective_schema) + return effective_schema + self.__call__ = schema_for_object + self.hash_key = ";".join( + "%s=%s" % (k, map_[k]) + for k in sorted(map_) + ) + self.is_default = False + else: + self.hash_key = 0 + self.__call__ = self._default_schema_getter + self.is_default = True + + @classmethod + def _schema_getter(cls, map_): + if map_ is None: + return _default_schema_map + elif isinstance(map_, _SchemaTranslateMap): + return map_ + else: + return _SchemaTranslateMap(map_) + +_default_schema_map = _SchemaTranslateMap(None) +_schema_getter = _SchemaTranslateMap._schema_getter + |