summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/engine/default.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/default.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/default.py')
-rw-r--r--lib/sqlalchemy/engine/default.py36
1 files changed, 25 insertions, 11 deletions
diff --git a/lib/sqlalchemy/engine/default.py b/lib/sqlalchemy/engine/default.py
index 865a1160b..20f731116 100644
--- a/lib/sqlalchemy/engine/default.py
+++ b/lib/sqlalchemy/engine/default.py
@@ -18,8 +18,8 @@ import random
import re
import weakref
+from . import cursor as _cursor
from . import interfaces
-from . import result as _result
from .. import event
from .. import exc
from .. import pool
@@ -1217,9 +1217,9 @@ class DefaultExecutionContext(interfaces.ExecutionContext):
def get_result_cursor_strategy(self, result):
if self._is_server_side:
- strat_cls = _result.BufferedRowCursorFetchStrategy
+ strat_cls = _cursor.BufferedRowCursorFetchStrategy
else:
- strat_cls = _result.DefaultCursorFetchStrategy
+ strat_cls = _cursor.CursorFetchStrategy
return strat_cls.create(result)
@@ -1237,7 +1237,7 @@ class DefaultExecutionContext(interfaces.ExecutionContext):
if self.is_crud or self.is_text:
result = self._setup_crud_result_proxy()
else:
- result = _result.ResultProxy._create_for_context(self)
+ result = _cursor.CursorResult._create_for_context(self)
if (
self.compiled
@@ -1289,25 +1289,39 @@ class DefaultExecutionContext(interfaces.ExecutionContext):
elif not self._is_implicit_returning:
self._setup_ins_pk_from_empty()
- result = _result.ResultProxy._create_for_context(self)
+ result = _cursor.CursorResult._create_for_context(self)
if self.isinsert:
if self._is_implicit_returning:
- row = result._onerow()
+ row = result.fetchone()
self.returned_defaults = row
self._setup_ins_pk_from_implicit_returning(row)
+
+ # test that it has a cursor metadata that is accurate.
+ # the first row will have been fetched and current assumptions
+ # are that the result has only one row, until executemany()
+ # support is added here.
+ assert result.returns_rows
result._soft_close()
- result._metadata = None
elif not self._is_explicit_returning:
result._soft_close()
- result._metadata = None
+
+ # we assume here the result does not return any rows.
+ # *usually*, this will be true. However, some dialects
+ # such as that of MSSQL/pyodbc need to SELECT a post fetch
+ # function so this is not necessarily true.
+ # assert not result.returns_rows
+
elif self.isupdate and self._is_implicit_returning:
- row = result._onerow()
+ row = result.fetchone()
self.returned_defaults = row
result._soft_close()
- result._metadata = None
- elif result._metadata is None:
+ # test that it has a cursor metadata that is accurate.
+ # the rows have all been fetched however.
+ assert result.returns_rows
+
+ elif not result.returns_rows:
# no results, get rowcount
# (which requires open cursor on some drivers
# such as kintersbasdb, mxodbc)