Skip to content

Commit 4ae9a15

Browse files
committed
INTPYTHON-348 add support for QuerySet.raw_mql()
1 parent 087000e commit 4ae9a15

File tree

2 files changed

+57
-1
lines changed

2 files changed

+57
-1
lines changed

django_mongodb/manager.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
from django.db.models.manager import BaseManager
2+
3+
from .query import MongoQuerySet
4+
5+
6+
class MongoManager(BaseManager.from_queryset(MongoQuerySet)):
7+
pass

django_mongodb/query.py

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,14 @@
22
from operator import add as add_operator
33

44
from django.core.exceptions import EmptyResultSet, FullResultSet
5-
from django.db import DatabaseError, IntegrityError, NotSupportedError
5+
from django.db import DatabaseError, IntegrityError, NotSupportedError, connections
6+
from django.db.models import QuerySet
67
from django.db.models.expressions import Case, Col, When
78
from django.db.models.functions import Mod
89
from django.db.models.lookups import Exact
910
from django.db.models.sql.constants import INNER
1011
from django.db.models.sql.datastructures import Join
12+
from django.db.models.sql.query import RawQuery, RawQuerySet
1113
from django.db.models.sql.where import AND, OR, XOR, ExtraWhere, NothingNode, WhereNode
1214
from pymongo.errors import BulkWriteError, DuplicateKeyError, PyMongoError
1315

@@ -302,3 +304,50 @@ def register_nodes():
302304
Join.as_mql = join
303305
NothingNode.as_mql = NothingNode.as_sql
304306
WhereNode.as_mql = where_node
307+
308+
309+
class MongoQuerySet(QuerySet):
310+
def raw_mql(self, raw_query, params=(), translations=None, using=None):
311+
return MongoRawQuerySet(
312+
raw_query,
313+
model=self.model,
314+
params=params,
315+
translations=translations,
316+
using=using,
317+
)
318+
319+
320+
class MongoRawQuery(RawQuery):
321+
def _execute_query(self):
322+
connection = connections[self.using]
323+
params_type = self.params_type
324+
adapter = connection.ops.adapt_unknown_value
325+
if params_type is tuple:
326+
params = tuple(adapter(val) for val in self.params)
327+
elif params_type is dict:
328+
params = {key: adapter(val) for key, val in self.params.items()}
329+
elif params_type is None:
330+
params = None
331+
else:
332+
raise RuntimeError("Unexpected params type: %s" % params_type)
333+
334+
self.cursor = connection.cursor()
335+
self.cursor.execute(self.sql, params)
336+
337+
338+
class MongoRawQuerySet(RawQuerySet):
339+
def __init__(
340+
self,
341+
raw_query,
342+
model=None,
343+
query=None,
344+
params=(),
345+
translations=None,
346+
using=None,
347+
hints=None,
348+
):
349+
self.model = model
350+
self._db = using
351+
self._hints = hints or {}
352+
self.query = query or MongoRawQuery(sql=raw_query, using=self.db, params=params)
353+
self._result_cache = None

0 commit comments

Comments
 (0)