summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy
diff options
context:
space:
mode:
authormike bayer <mike_mp@zzzcomputing.com>2020-09-22 19:47:21 +0000
committerGerrit Code Review <gerrit@bbpush.zzzcomputing.com>2020-09-22 19:47:21 +0000
commit9e31cce582569dfe6fb33b33aadd43d70c2ae593 (patch)
tree0eaacdd685be3d3968d9a1f9e64294f864ba963f /lib/sqlalchemy
parentc3e9f76e8d29db35875cb7ee956fe29e49a6fc95 (diff)
parent96888aee7611c15532af2ae47e567f68c28b2474 (diff)
downloadsqlalchemy-9e31cce582569dfe6fb33b33aadd43d70c2ae593.tar.gz
Merge "Deprecate negative slice indexes"
Diffstat (limited to 'lib/sqlalchemy')
-rw-r--r--lib/sqlalchemy/orm/dynamic.py4
-rw-r--r--lib/sqlalchemy/orm/query.py6
-rw-r--r--lib/sqlalchemy/orm/util.py20
3 files changed, 25 insertions, 5 deletions
diff --git a/lib/sqlalchemy/orm/dynamic.py b/lib/sqlalchemy/orm/dynamic.py
index af67b4772..48161a256 100644
--- a/lib/sqlalchemy/orm/dynamic.py
+++ b/lib/sqlalchemy/orm/dynamic.py
@@ -510,7 +510,9 @@ class AppenderQuery(Generative):
attributes.PASSIVE_NO_INITIALIZE,
).indexed(index)
else:
- return orm_util._getitem(self, index)
+ return orm_util._getitem(
+ self, index, allow_negative=not self.session.future
+ )
@_generative
def limit(self, limit):
diff --git a/lib/sqlalchemy/orm/query.py b/lib/sqlalchemy/orm/query.py
index c6e6f6466..42987932d 100644
--- a/lib/sqlalchemy/orm/query.py
+++ b/lib/sqlalchemy/orm/query.py
@@ -2495,7 +2495,11 @@ class Query(
self._compile_options += {"_enable_single_crit": False}
def __getitem__(self, item):
- return orm_util._getitem(self, item)
+ return orm_util._getitem(
+ self,
+ item,
+ allow_negative=not self.session or not self.session.future,
+ )
@_generative
@_assertions(_no_statement_condition)
diff --git a/lib/sqlalchemy/orm/util.py b/lib/sqlalchemy/orm/util.py
index 27b14d95b..c8d639e8c 100644
--- a/lib/sqlalchemy/orm/util.py
+++ b/lib/sqlalchemy/orm/util.py
@@ -1811,12 +1811,26 @@ def randomize_unitofwork():
) = session.set = mapper.set = dependency.set = RandomSet
-def _getitem(iterable_query, item):
+def _getitem(iterable_query, item, allow_negative):
"""calculate __getitem__ in terms of an iterable query object
that also has a slice() method.
"""
+ def _no_negative_indexes():
+ if not allow_negative:
+ raise IndexError(
+ "negative indexes are not accepted by SQL "
+ "index / slice operators"
+ )
+ else:
+ util.warn_deprecated_20(
+ "Support for negative indexes for SQL index / slice operators "
+ "will be "
+ "removed in 2.0; these operators fetch the complete result "
+ "and do not work efficiently."
+ )
+
if isinstance(item, slice):
start, stop, step = util.decode_slice(item)
@@ -1827,11 +1841,10 @@ def _getitem(iterable_query, item):
):
return []
- # perhaps we should execute a count() here so that we
- # can still use LIMIT/OFFSET ?
elif (isinstance(start, int) and start < 0) or (
isinstance(stop, int) and stop < 0
):
+ _no_negative_indexes()
return list(iterable_query)[item]
res = iterable_query.slice(start, stop)
@@ -1841,6 +1854,7 @@ def _getitem(iterable_query, item):
return list(res)
else:
if item == -1:
+ _no_negative_indexes()
return list(iterable_query)[-1]
else:
return list(iterable_query[item : item + 1])[0]