diff options
Diffstat (limited to 'lib/sqlalchemy/engine')
-rw-r--r-- | lib/sqlalchemy/engine/__init__.py | 6 | ||||
-rw-r--r-- | lib/sqlalchemy/engine/base.py | 47 | ||||
-rw-r--r-- | lib/sqlalchemy/engine/default.py | 3 |
3 files changed, 44 insertions, 12 deletions
diff --git a/lib/sqlalchemy/engine/__init__.py b/lib/sqlalchemy/engine/__init__.py index 23b4b0b3b..c3667dd33 100644 --- a/lib/sqlalchemy/engine/__init__.py +++ b/lib/sqlalchemy/engine/__init__.py @@ -143,6 +143,12 @@ def create_engine(*args, **kwargs): :class:`.String` type - see that type for further details. + :param case_sensitive=True: if False, result column names + will match in a case-insensitive fashion, that is, + ``row['SomeColumn']``. By default, result row names + match case-sensitively as of version 0.8. In version + 0.7 and prior, all matches were case-insensitive. + :param connect_args: a dictionary of options which will be passed directly to the DBAPI's ``connect()`` method as additional keyword arguments. See the example diff --git a/lib/sqlalchemy/engine/base.py b/lib/sqlalchemy/engine/base.py index 1d2511333..93d2b19f1 100644 --- a/lib/sqlalchemy/engine/base.py +++ b/lib/sqlalchemy/engine/base.py @@ -2724,6 +2724,7 @@ class ResultMetaData(object): dialect = context.dialect typemap = dialect.dbapi_type_map translate_colname = dialect._translate_colname + self.case_sensitive = dialect.case_sensitive # high precedence key values. primary_keymap = {} @@ -2738,9 +2739,14 @@ class ResultMetaData(object): if translate_colname: colname, untranslated = translate_colname(colname) + if dialect.requires_name_normalize: + colname = dialect.normalize_name(colname) + if context.result_map: try: - name, obj, type_ = context.result_map[colname.lower()] + name, obj, type_ = context.result_map[colname + if self.case_sensitive + else colname.lower()] except KeyError: name, obj, type_ = \ colname, None, typemap.get(coltype, types.NULLTYPE) @@ -2758,17 +2764,20 @@ class ResultMetaData(object): primary_keymap[i] = rec # populate primary keymap, looking for conflicts. - if primary_keymap.setdefault(name.lower(), rec) is not rec: + if primary_keymap.setdefault( + name if self.case_sensitive + else name.lower(), + rec) is not rec: # place a record that doesn't have the "index" - this # is interpreted later as an AmbiguousColumnError, # but only when actually accessed. Columns # colliding by name is not a problem if those names # aren't used; integer and ColumnElement access is always # unambiguous. - primary_keymap[name.lower()] = (processor, obj, None) + primary_keymap[name + if self.case_sensitive + else name.lower()] = (processor, obj, None) - if dialect.requires_name_normalize: - colname = dialect.normalize_name(colname) self.keys.append(colname) if obj: @@ -2797,7 +2806,9 @@ class ResultMetaData(object): row. """ - rec = (processor, obj, i) = self._keymap[origname.lower()] + rec = (processor, obj, i) = self._keymap[origname if + self.case_sensitive + else origname.lower()] if self._keymap.setdefault(name, rec) is not rec: self._keymap[name] = (processor, obj, None) @@ -2805,17 +2816,27 @@ class ResultMetaData(object): map = self._keymap result = None if isinstance(key, basestring): - result = map.get(key.lower()) + result = map.get(key if self.case_sensitive else key.lower()) # fallback for targeting a ColumnElement to a textual expression # this is a rare use case which only occurs when matching text() # or colummn('name') constructs to ColumnElements, or after a # pickle/unpickle roundtrip elif isinstance(key, expression.ColumnElement): - if key._label and key._label.lower() in map: - result = map[key._label.lower()] - elif hasattr(key, 'name') and key.name.lower() in map: + if key._label and ( + key._label + if self.case_sensitive + else key._label.lower()) in map: + result = map[key._label + if self.case_sensitive + else key._label.lower()] + elif hasattr(key, 'name') and ( + key.name + if self.case_sensitive + else key.name.lower()) in map: # match is only on name. - result = map[key.name.lower()] + result = map[key.name + if self.case_sensitive + else key.name.lower()] # search extra hard to make sure this # isn't a column/label name overlap. # this check isn't currently available if the row @@ -2851,7 +2872,8 @@ class ResultMetaData(object): for key, (processor, obj, index) in self._keymap.iteritems() if isinstance(key, (basestring, int)) ), - 'keys': self.keys + 'keys': self.keys, + "case_sensitive":self.case_sensitive, } def __setstate__(self, state): @@ -2864,6 +2886,7 @@ class ResultMetaData(object): # proxy comparison fails with the unpickle keymap[key] = (None, None, index) self.keys = state['keys'] + self.case_sensitive = state['case_sensitive'] self._echo = False diff --git a/lib/sqlalchemy/engine/default.py b/lib/sqlalchemy/engine/default.py index d0cbe871f..1f72d005d 100644 --- a/lib/sqlalchemy/engine/default.py +++ b/lib/sqlalchemy/engine/default.py @@ -105,6 +105,7 @@ class DefaultDialect(base.Dialect): def __init__(self, convert_unicode=False, assert_unicode=False, encoding='utf-8', paramstyle=None, dbapi=None, implicit_returning=None, + case_sensitive=True, label_length=None, **kwargs): if not getattr(self, 'ported_sqla_06', True): @@ -139,6 +140,8 @@ class DefaultDialect(base.Dialect): self.identifier_preparer = self.preparer(self) self.type_compiler = self.type_compiler(self) + self.case_sensitive = case_sensitive + if label_length and label_length > self.max_identifier_length: raise exc.ArgumentError( "Label length of %d is greater than this dialect's" |