Skip to content

Commit edb9ec9

Browse files
committed
raise NotSupportedError for Subquery, Exists, and QuerySet in annotate()
1 parent c769dcc commit edb9ec9

File tree

3 files changed

+38
-18
lines changed

3 files changed

+38
-18
lines changed

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,9 @@ Migrations for 'admin':
116116
- `extra()`
117117
- `select_related()`
118118

119+
- `Subquery`, `Exists`, and using a `QuerySet` in `QuerySet.annotate()` aren't
120+
supported.
121+
119122
- Queries with joins aren't supported.
120123

121124
- `DateTimeField` doesn't support microsecond precision, and correspondingly,

django_mongodb/expressions.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,18 @@
33

44
from bson import Decimal128
55
from django.core.exceptions import EmptyResultSet, FullResultSet
6+
from django.db import NotSupportedError
67
from django.db.models.expressions import (
78
Case,
89
Col,
910
CombinedExpression,
1011
ExpressionWrapper,
1112
NegatedExpression,
13+
Subquery,
1214
Value,
1315
When,
1416
)
17+
from django.db.models.sql import Query
1518

1619

1720
def case(self, compiler, connection):
@@ -59,6 +62,14 @@ def negated_expression(self, compiler, connection):
5962
return {"$not": expression_wrapper(self, compiler, connection)}
6063

6164

65+
def query(self, compiler, connection): # noqa: ARG001
66+
raise NotSupportedError("Using a QuerySet in annotate() is not supported on MongoDB.")
67+
68+
69+
def subquery(self, compiler, connection): # noqa: ARG001
70+
raise NotSupportedError(f"{self.__class__.__name__} is not supported on MongoDB.")
71+
72+
6273
def when(self, compiler, connection):
6374
return self.condition.as_mql(compiler, connection)
6475

@@ -82,5 +93,7 @@ def register_expressions():
8293
CombinedExpression.as_mql = combined_expression
8394
ExpressionWrapper.as_mql = expression_wrapper
8495
NegatedExpression.as_mql = negated_expression
96+
Query.as_mql = query
97+
Subquery.as_mql = subquery
8598
When.as_mql = when
8699
Value.as_mql = value

django_mongodb/features.py

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -59,10 +59,6 @@ class DatabaseFeatures(BaseDatabaseFeatures):
5959
# the result back to UTC.
6060
"db_functions.datetime.test_extract_trunc.DateFunctionWithTimeZoneTests.test_trunc_func_with_timezone",
6161
"db_functions.datetime.test_extract_trunc.DateFunctionWithTimeZoneTests.test_trunc_timezone_applied_before_truncation",
62-
# pk__in=queryset doesn't work because subqueries aren't a thing in
63-
# MongoDB.
64-
"annotations.tests.NonAggregateAnnotationTestCase.test_annotation_and_alias_filter_in_subquery",
65-
"model_fields.test_jsonfield.TestQuerying.test_usage_in_subquery",
6662
# Length of null considered zero rather than null.
6763
"db_functions.text.test_length.LengthTests.test_basic",
6864
# Key transforms are incorrectly treated as joins:
@@ -220,25 +216,11 @@ def django_test_expected_failures(self):
220216
"timezones.tests.NewDatabaseTests.test_query_aggregation",
221217
},
222218
"QuerySet.annotate() has some limitations.": {
223-
# Exists not supported.
224-
"annotations.tests.NonAggregateAnnotationTestCase.test_annotation_exists_none_query",
225-
"lookup.tests.LookupTests.test_exact_exists",
226-
"lookup.tests.LookupTests.test_nested_outerref_lhs",
227-
"lookup.tests.LookupQueryingTests.test_filter_exists_lhs",
228219
# annotate() with combined expressions doesn't work:
229220
# 'WhereNode' object has no attribute 'field'
230221
"lookup.tests.LookupQueryingTests.test_combined_annotated_lookups_in_filter",
231222
"lookup.tests.LookupQueryingTests.test_combined_annotated_lookups_in_filter_false",
232223
"lookup.tests.LookupQueryingTests.test_combined_lookups",
233-
# Subquery not supported.
234-
"annotations.tests.NonAggregateAnnotationTestCase.test_empty_queryset_annotation",
235-
"db_functions.comparison.test_coalesce.CoalesceTests.test_empty_queryset",
236-
"db_functions.datetime.test_extract_trunc.DateFunctionTests.test_extract_outerref",
237-
"db_functions.datetime.test_extract_trunc.DateFunctionTests.test_trunc_subquery_with_parameters",
238-
"expressions_case.tests.CaseExpressionTests.test_in_subquery",
239-
"lookup.tests.LookupQueryingTests.test_filter_subquery_lhs",
240-
"model_fields.test_jsonfield.TestQuerying.test_nested_key_transform_on_subquery",
241-
"model_fields.test_jsonfield.TestQuerying.test_obj_subquery_lookup",
242224
# Invalid $project :: caused by :: Unknown expression $count,
243225
"annotations.tests.NonAggregateAnnotationTestCase.test_combined_expression_annotation_with_aggregation",
244226
"annotations.tests.NonAggregateAnnotationTestCase.test_combined_f_expression_annotation_with_aggregation",
@@ -263,6 +245,28 @@ def django_test_expected_failures(self):
263245
# annotate().filter().count() gives incorrect results.
264246
"db_functions.datetime.test_extract_trunc.DateFunctionTests.test_extract_year_exact_lookup",
265247
},
248+
"Exists is not supported on MongoDB.": {
249+
"annotations.tests.NonAggregateAnnotationTestCase.test_annotation_exists_none_query",
250+
"lookup.tests.LookupTests.test_exact_exists",
251+
"lookup.tests.LookupTests.test_nested_outerref_lhs",
252+
"lookup.tests.LookupQueryingTests.test_filter_exists_lhs",
253+
},
254+
"Subquery is not supported on MongoDB.": {
255+
"annotations.tests.NonAggregateAnnotationTestCase.test_empty_queryset_annotation",
256+
"db_functions.datetime.test_extract_trunc.DateFunctionTests.test_extract_outerref",
257+
"db_functions.datetime.test_extract_trunc.DateFunctionTests.test_trunc_subquery_with_parameters",
258+
"lookup.tests.LookupQueryingTests.test_filter_subquery_lhs",
259+
"model_fields.test_jsonfield.TestQuerying.test_nested_key_transform_on_subquery",
260+
"model_fields.test_jsonfield.TestQuerying.test_obj_subquery_lookup",
261+
},
262+
"Using a QuerySet in annotate() is not supported on MongoDB.": {
263+
"annotations.tests.NonAggregateAnnotationTestCase.test_annotation_and_alias_filter_in_subquery",
264+
"annotations.tests.NonAggregateAnnotationTestCase.test_empty_expression_annotation",
265+
"db_functions.comparison.test_coalesce.CoalesceTests.test_empty_queryset",
266+
"expressions_case.tests.CaseExpressionTests.test_in_subquery",
267+
"lookup.tests.LookupTests.test_in_different_database",
268+
"model_fields.test_jsonfield.TestQuerying.test_usage_in_subquery",
269+
},
266270
"Count doesn't work in QuerySet.annotate()": {
267271
"annotations.tests.AliasTests.test_alias_annotate_with_aggregation",
268272
"annotations.tests.AliasTests.test_order_by_alias_aggregate",

0 commit comments

Comments
 (0)