From aded39f68c29e44a50c85be1ddb370d3d1affe9d Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Tue, 21 Apr 2020 12:51:13 -0400 Subject: 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 --- lib/sqlalchemy/dialects/mssql/base.py | 4 ++-- lib/sqlalchemy/dialects/oracle/cx_oracle.py | 31 ++++++++--------------------- 2 files changed, 10 insertions(+), 25 deletions(-) (limited to 'lib/sqlalchemy/dialects') diff --git a/lib/sqlalchemy/dialects/mssql/base.py b/lib/sqlalchemy/dialects/mssql/base.py index dda445743..5618a67f9 100644 --- a/lib/sqlalchemy/dialects/mssql/base.py +++ b/lib/sqlalchemy/dialects/mssql/base.py @@ -704,9 +704,9 @@ from ... import schema as sa_schema from ... import sql from ... import types as sqltypes from ... import util +from ...engine import cursor as _cursor from ...engine import default from ...engine import reflection -from ...engine import result as _result from ...sql import compiler from ...sql import elements from ...sql import expression @@ -1525,7 +1525,7 @@ class MSExecutionContext(default.DefaultExecutionContext): elif ( self.isinsert or self.isupdate or self.isdelete ) and self.compiled.returning: - fbcr = _result.FullyBufferedCursorFetchStrategy + fbcr = _cursor.FullyBufferedCursorFetchStrategy self._result_strategy = fbcr.create_from_buffer( self.cursor, self.cursor.description, self.cursor.fetchall() ) diff --git a/lib/sqlalchemy/dialects/oracle/cx_oracle.py b/lib/sqlalchemy/dialects/oracle/cx_oracle.py index b555c4555..9e10679c6 100644 --- a/lib/sqlalchemy/dialects/oracle/cx_oracle.py +++ b/lib/sqlalchemy/dialects/oracle/cx_oracle.py @@ -299,7 +299,6 @@ SQLAlchemy type (or a subclass of such). from __future__ import absolute_import -import collections import decimal import random import re @@ -312,7 +311,7 @@ from ... import exc from ... import processors from ... import types as sqltypes from ... import util -from ...engine import result as _result +from ...engine import cursor as _cursor from ...util import compat @@ -680,8 +679,13 @@ class OracleExecutionContext_cx_oracle(OracleExecutionContext): for i in range(len(self.out_parameters)) ] - return ReturningResultStrategy( - result, result.cursor, returning_params + return _cursor.FullyBufferedCursorFetchStrategy( + result.cursor, + [ + (getattr(col, "name", col.anon_label), None) + for col in result.context.compiled.returning + ], + initial_buffer=[tuple(returning_params)], ) else: return super( @@ -689,25 +693,6 @@ class OracleExecutionContext_cx_oracle(OracleExecutionContext): ).get_result_cursor_strategy(result) -class ReturningResultStrategy(_result.FullyBufferedCursorFetchStrategy): - __slots__ = ("_returning_params",) - - def __init__(self, result, dbapi_cursor, returning_params): - self._returning_params = returning_params - - returning = result.context.compiled.returning - cursor_description = [ - (getattr(col, "name", col.anon_label), None) for col in returning - ] - - super(ReturningResultStrategy, self).__init__( - dbapi_cursor, cursor_description - ) - - def _buffer_rows(self): - return collections.deque([tuple(self._returning_params)]) - - class OracleDialect_cx_oracle(OracleDialect): execution_ctx_cls = OracleExecutionContext_cx_oracle statement_compiler = OracleCompiler_cx_oracle -- cgit v1.2.1