summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGES15
-rw-r--r--lib/sqlalchemy/engine/base.py182
-rw-r--r--test/profiling/zoomark.py14
3 files changed, 106 insertions, 105 deletions
diff --git a/CHANGES b/CHANGES
index b00571833..78f943593 100644
--- a/CHANGES
+++ b/CHANGES
@@ -5,21 +5,24 @@ CHANGES
0.4.0beta7
----------
-- Added partial index support for PostgreSQL. Use the postgres_where
- keyword on the Index.
+- Added partial index support for PostgreSQL. Use the postgres_where keyword
+ on the Index.
- The IdentifierPreprarer's _requires_quotes test is now regex based. Any
out-of-tree dialects that provide custom sets of legal_characters or
illegal_initial_characters will need to move to regexes or override
_requires_quotes.
-- firebird has supports_sane_rowcount and supports_sane_multi_rowcount set
+- Firebird has supports_sane_rowcount and supports_sane_multi_rowcount set
to False due to ticket #370 (right way).
-- fixed three- and multi-level select and deferred inheritance
- loading (i.e. abc inheritance with no select_table), [ticket:795]
+- Fixed three- and multi-level select and deferred inheritance loading
+ (i.e. abc inheritance with no select_table), [ticket:795]
-- ident passed to id_chooser in shard.py always a list
+- Ident passed to id_chooser in shard.py always a list.
+
+- The no-arg ResultProxy._row_processor() is now the class attribute
+ `_process_row`.
0.4.0beta6
----------
diff --git a/lib/sqlalchemy/engine/base.py b/lib/sqlalchemy/engine/base.py
index e385072ad..fa58657dc 100644
--- a/lib/sqlalchemy/engine/base.py
+++ b/lib/sqlalchemy/engine/base.py
@@ -1188,6 +1188,89 @@ class Engine(Connectable):
return self.pool.unique_connection()
+
+class RowProxy(object):
+ """Proxy a single cursor row for a parent ResultProxy.
+
+ Mostly follows "ordered dictionary" behavior, mapping result
+ values to the string-based column name, the integer position of
+ the result in the row, as well as Column instances which can be
+ mapped to the original Columns that produced this result set (for
+ results that correspond to constructed SQL expressions).
+ """
+
+ def __init__(self, parent, row):
+ """RowProxy objects are constructed by ResultProxy objects."""
+
+ self.__parent = parent
+ self.__row = row
+ if self.__parent._ResultProxy__echo:
+ self.__parent.context.engine.logger.debug("Row " + repr(row))
+
+ def close(self):
+ """Close the parent ResultProxy."""
+
+ self.__parent.close()
+
+ def __contains__(self, key):
+ return self.__parent._has_key(self.__row, key)
+
+ def __len__(self):
+ return len(self.__row)
+
+ def __iter__(self):
+ for i in xrange(len(self.__row)):
+ yield self.__parent._get_col(self.__row, i)
+
+ def __eq__(self, other):
+ return ((other is self) or
+ (other == tuple([self.__parent._get_col(self.__row, key)
+ for key in xrange(len(self.__row))])))
+
+ def __repr__(self):
+ return repr(tuple(self))
+
+ def has_key(self, key):
+ """Return True if this RowProxy contains the given key."""
+
+ return self.__parent._has_key(self.__row, key)
+
+ def __getitem__(self, key):
+ if isinstance(key, slice):
+ indices = key.indices(len(self))
+ return tuple([self.__parent._get_col(self.__row, i)
+ for i in xrange(*indices)])
+ else:
+ return self.__parent._get_col(self.__row, key)
+
+ def __getattr__(self, name):
+ try:
+ return self.__parent._get_col(self.__row, name)
+ except KeyError, e:
+ raise AttributeError(e.args[0])
+
+ def items(self):
+ """Return a list of tuples, each tuple containing a key/value pair."""
+
+ return [(key, getattr(self, key)) for key in self.keys()]
+
+ def keys(self):
+ """Return the list of keys as strings represented by this RowProxy."""
+
+ return self.__parent.keys
+
+ def values(self):
+ """Return the values represented by this RowProxy as a list."""
+
+ return list(self)
+
+
+class BufferedColumnRow(RowProxy):
+ def __init__(self, parent, row):
+ row = [ResultProxy._get_col(parent, row, i) for i in xrange(len(row))]
+ super(BufferedColumnRow, self).__init__(parent, row)
+
+
class ResultProxy(object):
"""Wraps a DB-API cursor object to provide easier access to row columns.
@@ -1210,10 +1293,7 @@ class ResultProxy(object):
to obtain information from the underlying ExecutionContext.
"""
- def __ambiguous_processor(self, colname):
- def process(value):
- raise exceptions.InvalidRequestError("Ambiguous column name '%s' in result set! try 'use_labels' option on select statement." % colname)
- return process
+ _process_row = RowProxy
def __init__(self, context):
"""ResultProxy objects are constructed via the execute() method on SQLEngine."""
@@ -1222,7 +1302,6 @@ class ResultProxy(object):
self.closed = False
self.cursor = context.cursor
self.__echo = context.engine._should_log_info
- self._process_row = self._row_processor()
if context.is_select():
self._init_metadata()
self._rowcount = None
@@ -1296,6 +1375,11 @@ class ResultProxy(object):
return rec
return util.PopulateDict(lookup_key)
+ def __ambiguous_processor(self, colname):
+ def process(value):
+ raise exceptions.InvalidRequestError("Ambiguous column name '%s' in result set! try 'use_labels' option on select statement." % colname)
+ return process
+
def close(self):
"""Close this ResultProxy, and the underlying DB-API cursor corresponding to the execution.
@@ -1394,9 +1478,6 @@ class ResultProxy(object):
def _fetchall_impl(self):
return self.cursor.fetchall()
- def _row_processor(self):
- return RowProxy
-
def fetchall(self):
"""Fetch all rows, just like DB-API ``cursor.fetchall()``."""
@@ -1500,14 +1581,12 @@ class BufferedColumnResultProxy(ResultProxy):
cx_Oracle LOB objects, but this behavior is known to exist in
other DB-APIs as well (Pygresql, currently unsupported).
"""
+ _process_row = BufferedColumnRow
def _get_col(self, row, key):
rec = self._key_cache[key]
return row[rec[2]]
- def _row_processor(self):
- return BufferedColumnRow
-
def fetchall(self):
l = []
while True:
@@ -1528,87 +1607,6 @@ class BufferedColumnResultProxy(ResultProxy):
l.append(row)
return l
-class RowProxy(object):
- """Proxy a single cursor row for a parent ResultProxy.
-
- Mostly follows "ordered dictionary" behavior, mapping result
- values to the string-based column name, the integer position of
- the result in the row, as well as Column instances which can be
- mapped to the original Columns that produced this result set (for
- results that correspond to constructed SQL expressions).
- """
-
- def __init__(self, parent, row):
- """RowProxy objects are constructed by ResultProxy objects."""
-
- self.__parent = parent
- self.__row = row
- if self.__parent._ResultProxy__echo:
- self.__parent.context.engine.logger.debug("Row " + repr(row))
-
- def close(self):
- """Close the parent ResultProxy."""
-
- self.__parent.close()
-
- def __contains__(self, key):
- return self.__parent._has_key(self.__row, key)
-
- def __len__(self):
- return len(self.__row)
-
- def __iter__(self):
- for i in range(0, len(self.__row)):
- yield self.__parent._get_col(self.__row, i)
-
- def __eq__(self, other):
- return ((other is self) or
- (other == tuple([self.__parent._get_col(self.__row, key)
- for key in range(len(self.__row))])))
-
- def __repr__(self):
- return repr(tuple([self.__parent._get_col(self.__row, key)
- for key in range(len(self.__row))]))
-
- def has_key(self, key):
- """Return True if this RowProxy contains the given key."""
-
- return self.__parent._has_key(self.__row, key)
-
- def __getitem__(self, key):
- if isinstance(key, slice):
- indices = key.indices(len(self))
- return tuple([self.__parent._get_col(self.__row, i)
- for i in range(*indices)])
- else:
- return self.__parent._get_col(self.__row, key)
-
- def __getattr__(self, name):
- try:
- return self.__parent._get_col(self.__row, name)
- except KeyError, e:
- raise AttributeError(e.args[0])
-
- def items(self):
- """Return a list of tuples, each tuple containing a key/value pair."""
-
- return [(key, getattr(self, key)) for key in self.keys()]
-
- def keys(self):
- """Return the list of keys as strings represented by this RowProxy."""
-
- return self.__parent.keys
-
- def values(self):
- """Return the values represented by this RowProxy as a list."""
-
- return list(self)
-
-
-class BufferedColumnRow(RowProxy):
- def __init__(self, parent, row):
- row = [ResultProxy._get_col(parent, row, i) for i in xrange(len(row))]
- super(BufferedColumnRow, self).__init__(parent, row)
class SchemaIterator(schema.SchemaVisitor):
"""A visitor that can gather text into a buffer and execute the contents of the buffer."""
diff --git a/test/profiling/zoomark.py b/test/profiling/zoomark.py
index 410c7756f..4feab2fc8 100644
--- a/test/profiling/zoomark.py
+++ b/test/profiling/zoomark.py
@@ -44,7 +44,7 @@ class ZooMarkTest(testing.AssertMixin):
metadata.create_all()
@testing.supported('postgres')
- @profiling.profiled('populate', call_range=(4350, 4410), always=True)
+ @profiling.profiled('populate', call_range=(4340, 4400), always=True)
def test_1a_populate(self):
Zoo = metadata.tables['Zoo']
Animal = metadata.tables['Animal']
@@ -112,7 +112,7 @@ class ZooMarkTest(testing.AssertMixin):
MotherID=bai_yun)
@testing.supported('postgres')
- @profiling.profiled('insert', call_range=(230, 250), always=True)
+ @profiling.profiled('insert', call_range=(230, 250), always=True)
def test_2_insert(self):
Animal = metadata.tables['Animal']
i = Animal.insert()
@@ -120,7 +120,7 @@ class ZooMarkTest(testing.AssertMixin):
tick = i.execute(Species='Tick', Name='Tick %d' % x, Legs=8)
@testing.supported('postgres')
- @profiling.profiled('properties', call_range=(3430, 3440), always=True)
+ @profiling.profiled('properties', call_range=(3420, 3430), always=True)
def test_3_properties(self):
Zoo = metadata.tables['Zoo']
Animal = metadata.tables['Animal']
@@ -143,7 +143,7 @@ class ZooMarkTest(testing.AssertMixin):
ticks = fullobject(Animal.select(Animal.c.Species=='Tick'))
@testing.supported('postgres')
- @profiling.profiled('expressions', call_range=(12595, 12605), always=True)
+ @profiling.profiled('expressions', call_range=(12570, 12580), always=True)
def test_4_expressions(self):
Zoo = metadata.tables['Zoo']
Animal = metadata.tables['Animal']
@@ -197,7 +197,7 @@ class ZooMarkTest(testing.AssertMixin):
assert len(fulltable(Animal.select(func.date_part('day', Animal.c.LastEscape) == 21))) == 1
@testing.supported('postgres')
- @profiling.profiled('aggregates', call_range=(1220, 1230), always=True)
+ @profiling.profiled('aggregates', call_range=(1220, 1230), always=True)
def test_5_aggregates(self):
Animal = metadata.tables['Animal']
Zoo = metadata.tables['Zoo']
@@ -239,7 +239,7 @@ class ZooMarkTest(testing.AssertMixin):
legs.sort()
@testing.supported('postgres')
- @profiling.profiled('editing', call_range=(1380, 1390), always=True)
+ @profiling.profiled('editing', call_range=(1370, 1380), always=True)
def test_6_editing(self):
Zoo = metadata.tables['Zoo']
@@ -268,7 +268,7 @@ class ZooMarkTest(testing.AssertMixin):
assert SDZ['Founded'] == datetime.date(1935, 9, 13)
@testing.supported('postgres')
- @profiling.profiled('multiview', call_range=(3090, 3100), always=True)
+ @profiling.profiled('multiview', call_range=(3080, 3090), always=True)
def test_7_multiview(self):
Zoo = metadata.tables['Zoo']
Animal = metadata.tables['Animal']