summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/engine/row.py
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2020-04-21 12:51:13 -0400
committerMike Bayer <mike_mp@zzzcomputing.com>2020-05-01 16:09:24 -0400
commitaded39f68c29e44a50c85be1ddb370d3d1affe9d (patch)
tree0855ecfe2ecf5092f1e350c33f460571f495f1b8 /lib/sqlalchemy/engine/row.py
parent18ce4f9937c2d6753acbb054b4990c7da298a5d7 (diff)
downloadsqlalchemy-aded39f68c29e44a50c85be1ddb370d3d1affe9d.tar.gz
Propose Result as immediate replacement for ResultProxy
As progress is made on the _future.Result, including breaking it out such that DBAPI behaviors are local to specific implementations, it becomes apparent that the Result object is a functional superset of ResultProxy and that basic operations like fetchone(), fetchall(), and fetchmany() behave pretty much exactly the same way on the new object. Reorganize things so that ResultProxy is now referred to as LegacyCursorResult, which subclasses CursorResult that represents the DBAPI-cursor version of Result, making use of a multiple inheritance pattern so that the functionality of Result is also available in non-DBAPI contexts, as will be necessary for some ORM patterns. Additionally propose the composition system for Result that will form the basis for ORM-alternative result systems such as horizontal sharding and dogpile cache. As ORM results will soon be coming directly from instances of Result, these extensions will instead build their own ResultFetchStrategies that perform the special steps to create composed or cached result sets. Also considering at the moment not emitting deprecation warnings for fetchXYZ() methods; the immediate issue is Keystone tests are calling upon it, but as the implementations here are proving to be not in any kind of conflict with how Result works, there's not too much issue leaving them around and deprecating at some later point. References: #5087 References: #4395 Fixes: #4959 Change-Id: I8091919d45421e3f53029b8660427f844fee0228
Diffstat (limited to 'lib/sqlalchemy/engine/row.py')
-rw-r--r--lib/sqlalchemy/engine/row.py25
1 files changed, 15 insertions, 10 deletions
diff --git a/lib/sqlalchemy/engine/row.py b/lib/sqlalchemy/engine/row.py
index 68e32057d..6cd020110 100644
--- a/lib/sqlalchemy/engine/row.py
+++ b/lib/sqlalchemy/engine/row.py
@@ -51,7 +51,7 @@ except ImportError:
__slots__ = ("_parent", "_data", "_keymap")
def __init__(self, parent, processors, keymap, data):
- """Row objects are constructed by ResultProxy objects."""
+ """Row objects are constructed by CursorResult objects."""
self._parent = parent
@@ -69,6 +69,9 @@ except ImportError:
(self.__class__, self.__getstate__()),
)
+ def _filter_on_values(self, filters):
+ return Row(self._parent, filters, self._keymap, self._data)
+
def _values_impl(self):
return list(self)
@@ -81,6 +84,9 @@ except ImportError:
def __hash__(self):
return hash(self._data)
+ def __getitem__(self, key):
+ return self._data[key]
+
def _subscript_impl(self, key, ismapping):
try:
rec = self._keymap[key]
@@ -127,7 +133,7 @@ class Row(BaseRow, collections_abc.Sequence):
The :class:`.Row` object represents a row of a database result. It is
typically associated in the 1.x series of SQLAlchemy with the
- :class:`_engine.ResultProxy` object, however is also used by the ORM for
+ :class:`_engine.CursorResult` object, however is also used by the ORM for
tuple-like results as of SQLAlchemy 1.4.
The :class:`.Row` object seeks to act as much like a Python named
@@ -150,7 +156,7 @@ class Row(BaseRow, collections_abc.Sequence):
and now acts mostly like a named tuple. Mapping-like functionality is
moved to the :attr:`.Row._mapping` attribute, but will remain available
in SQLAlchemy 1.x series via the :class:`.LegacyRow` class that is used
- by :class:`_engine.ResultProxy`.
+ by :class:`_engine.LegacyCursorResult`.
See :ref:`change_4710_core` for background
on this change.
@@ -182,9 +188,6 @@ class Row(BaseRow, collections_abc.Sequence):
def __contains__(self, key):
return key in self._data
- def __getitem__(self, key):
- return self._data[key]
-
def __getstate__(self):
return {"_parent": self._parent, "_data": self._data}
@@ -243,7 +246,7 @@ class Row(BaseRow, collections_abc.Sequence):
:attr:`.Row._mapping`
"""
- return [k for k in self._parent.keys if k is not None]
+ return self._parent.keys
@property
def _fields(self):
@@ -477,6 +480,9 @@ class RowMapping(collections_abc.Mapping):
def __contains__(self, key):
return self.row._parent._has_key(key)
+ def __repr__(self):
+ return repr(dict(self))
+
def items(self):
"""Return a view of key/value tuples for the elements in the
underlying :class:`.Row`.
@@ -489,9 +495,8 @@ class RowMapping(collections_abc.Mapping):
by the underlying :class:`.Row`.
"""
- return ROMappingView(
- self, [k for k in self.row._parent.keys if k is not None]
- )
+
+ return self.row._parent.keys
def values(self):
"""Return a view of values for the values represented in the