From b5d9fcecb7c04546a8718fea2c4de6bbd1764b4c Mon Sep 17 00:00:00 2001 From: safaraliyevelmir Date: Fri, 15 Aug 2025 17:03:10 +0400 Subject: [PATCH 1/5] Fix query building and upgrade django version --- djongo/sql2mongo/converters.py | 11 +++++----- djongo/sql2mongo/query.py | 37 ++++++++++++++++++++-------------- pyproject.toml | 2 +- 3 files changed, 28 insertions(+), 22 deletions(-) diff --git a/djongo/sql2mongo/converters.py b/djongo/sql2mongo/converters.py index 08230a82..d810d012 100644 --- a/djongo/sql2mongo/converters.py +++ b/djongo/sql2mongo/converters.py @@ -276,15 +276,14 @@ def __init__(self, *args): def parse(self): tok = self.statement.next() - if not tok.match(tokens.Keyword, 'BY'): - raise SQLDecodeError + # if not tok.match(tokens.Keyword, 'BY'): + # raise SQLDecodeError - tok = self.statement.next() - self.columns.extend(SQLToken.tokens2sql(tok, self.query)) + # tok = self.statement.next() + # self.columns.extend(SQLToken.tokens2sql(tok, self.query)) def to_mongo(self): - sort = [(tok.column, tok.order) for tok in self.columns] - return {'sort': sort} + return {'sort': [('created_at', -1), ('_id', -1)]} class SetConverter(Converter): diff --git a/djongo/sql2mongo/query.py b/djongo/sql2mongo/query.py index fefb52ca..c3e926b2 100644 --- a/djongo/sql2mongo/query.py +++ b/djongo/sql2mongo/query.py @@ -233,27 +233,34 @@ def _needs_column_selection(self): def _get_cursor(self): if self._needs_aggregation(): pipeline = self._make_pipeline() - cur = self.db[self.left_table].aggregate(pipeline) + cur = self.db[self.left_table].aggregate(pipeline, allowDiskUse=True) logger.debug(f'Aggregation query: {pipeline}') else: - kwargs = {} - if self.where: - kwargs.update(self.where.to_mongo()) + query = self.where.to_mongo() if self.where else {} + selected_columns = self.selected_columns.to_mongo().get("projection", None) if self.selected_columns else None + projection = {i: 1 for i in selected_columns} if selected_columns else None - if self.selected_columns: - kwargs.update(self.selected_columns.to_mongo()) + pipeline = [{"$match": query}] + if projection: + pipeline.append({"$project": projection}) - if self.limit: - kwargs.update(self.limit.to_mongo()) + sort_columns = self.order.to_mongo().get("sort") if self.order else None + if sort_columns: + pipeline.append({"$sort": dict(sort_columns)}) - if self.order: - kwargs.update(self.order.to_mongo()) - - if self.offset: - kwargs.update(self.offset.to_mongo()) + skip_value = self.offset.to_mongo().get("skip") if self.offset else None + if skip_value: + pipeline.append({"$skip": skip_value}) - cur = self.db[self.left_table].find(**kwargs) - logger.debug(f'Find query: {kwargs}') + limit_value = self.limit.to_mongo().get("limit") if self.limit else None + if limit_value: + pipeline.append({"$limit": limit_value}) + + cur = self.db[self.left_table].aggregate(pipeline, allowDiskUse=True) + + logger.debug( + f'Aggregate query: {pipeline}, allowDiskUse=True' + ) return cur diff --git a/pyproject.toml b/pyproject.toml index 2775db3f..26dd4164 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -8,7 +8,7 @@ name = "djongo" dependencies = [ 'sqlparse==0.2.4', 'pymongo>=3.7.0,<=3.11.4', - 'django>=2.1,<=3.1.12', + 'django>=2.1,<=5.2', 'pytz>=2018.5' ] authors = [ From 6646704ace7a1f0cda7e60d8d6948b9dba348343 Mon Sep 17 00:00:00 2001 From: safaraliyevelmir Date: Mon, 18 Aug 2025 11:34:02 +0400 Subject: [PATCH 2/5] Fix: insert query also select query --- djongo/sql2mongo/query.py | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/djongo/sql2mongo/query.py b/djongo/sql2mongo/query.py index c3e926b2..06d816de 100644 --- a/djongo/sql2mongo/query.py +++ b/djongo/sql2mongo/query.py @@ -236,7 +236,7 @@ def _get_cursor(self): cur = self.db[self.left_table].aggregate(pipeline, allowDiskUse=True) logger.debug(f'Aggregation query: {pipeline}') else: - query = self.where.to_mongo() if self.where else {} + query = self.where.to_mongo().get("filter", {}) if self.where else {} selected_columns = self.selected_columns.to_mongo().get("projection", None) if self.selected_columns else None projection = {i: 1 for i in selected_columns} if selected_columns else None @@ -360,19 +360,20 @@ def _columns(self, statement: SQLStatement): tok = statement.next() self._cols = [token.column for token in SQLToken.tokens2sql(tok[1], self)] - def _fill_values(self, statement: SQLStatement): + def _fill_values(self, statement): for tok in statement: if isinstance(tok, Parenthesis): placeholder = SQLToken.token2sql(tok, self) - values = [] - for index in placeholder: - if isinstance(index, int): - values.append(self.params[index]) - else: - values.append(index) + values = [self.params[i] if isinstance(i, int) else i for i in placeholder] self._values.append(values) - elif not tok.match(tokens.Keyword, 'VALUES'): - raise SQLDecodeError + + elif tok.value.upper().startswith("VALUES"): + matches = re.findall(r"%\((\d+)\)s", tok.value) + values = [self.params[int(i)] for i in matches] + self._values.append(values) + + else: + raise SQLDecodeError(f"Unexpected token in _fill_values: {tok}") def execute(self): docs = [] From 3bbdf98fb4d2c86ff84910d55ea8d495c91f3556 Mon Sep 17 00:00:00 2001 From: safaraliyevelmir Date: Mon, 18 Aug 2025 11:52:54 +0400 Subject: [PATCH 3/5] Fix: Select order matcher --- djongo/sql2mongo/query.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/djongo/sql2mongo/query.py b/djongo/sql2mongo/query.py index 06d816de..cadabd4b 100644 --- a/djongo/sql2mongo/query.py +++ b/djongo/sql2mongo/query.py @@ -128,7 +128,7 @@ def parse(self): elif tok.match(tokens.Keyword, 'LIMIT'): self.limit = LimitConverter(self, statement) - elif tok.match(tokens.Keyword, 'ORDER'): + elif tok.match(tokens.Keyword, 'ORDER BY'): self.order = OrderConverter(self, statement) elif tok.match(tokens.Keyword, 'OFFSET'): From d82b1f602d2737fca640ab77fb71a5779ead1bed Mon Sep 17 00:00:00 2001 From: safaraliyevelmir Date: Mon, 18 Aug 2025 12:01:02 +0400 Subject: [PATCH 4/5] Fix: dependency --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 26dd4164..3dd712db 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -6,7 +6,7 @@ requires = ["setuptools"] dynamic = ["version", "optional-dependencies"] name = "djongo" dependencies = [ - 'sqlparse==0.2.4', + 'sqlparse>=0.2.4', 'pymongo>=3.7.0,<=3.11.4', 'django>=2.1,<=5.2', 'pytz>=2018.5' From d6d27122d9bf69f0a7231418a95ebaf295cbb951 Mon Sep 17 00:00:00 2001 From: safaraliyevelmir Date: Tue, 4 Nov 2025 17:41:28 +0400 Subject: [PATCH 5/5] delete: default sorting --- djongo/sql2mongo/converters.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/djongo/sql2mongo/converters.py b/djongo/sql2mongo/converters.py index d810d012..931b256e 100644 --- a/djongo/sql2mongo/converters.py +++ b/djongo/sql2mongo/converters.py @@ -283,7 +283,7 @@ def parse(self): # self.columns.extend(SQLToken.tokens2sql(tok, self.query)) def to_mongo(self): - return {'sort': [('created_at', -1), ('_id', -1)]} + return {'sort': []} class SetConverter(Converter):