summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/engine/base.py
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2012-04-24 16:03:00 -0400
committerMike Bayer <mike_mp@zzzcomputing.com>2012-04-24 16:03:00 -0400
commit87bbba32bc54fa0253e9c81663df669dc355f5da (patch)
treeb0b59e889ec323a5f0b4bb58de752facb7dcd38e /lib/sqlalchemy/engine/base.py
parenta66861031a85063c9de8874559815f7ee0bab998 (diff)
downloadsqlalchemy-87bbba32bc54fa0253e9c81663df669dc355f5da.tar.gz
- [feature] The behavior of column targeting
in result sets is now case sensitive by default. SQLAlchemy for many years would run a case-insensitive conversion on these values, probably to alleviate early case sensitivity issues with dialects like Oracle and Firebird. These issues have been more cleanly solved in more modern versions so the performance hit of calling lower() on identifiers is removed. The case insensitive comparisons can be re-enabled by setting "case_insensitive=False" on create_engine(). [ticket:2423]
Diffstat (limited to 'lib/sqlalchemy/engine/base.py')
-rw-r--r--lib/sqlalchemy/engine/base.py47
1 files changed, 35 insertions, 12 deletions
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