From 681de1238307183e81537ad56b4cca4024c30f4d Mon Sep 17 00:00:00 2001 From: Jongmin Kim Date: Wed, 1 May 2024 20:56:47 +0900 Subject: [PATCH 1/2] refactor: refactor group_by option Signed-off-by: Jongmin Kim --- .../core/model/mongo_model/__init__.py | 137 ++++++++++-------- 1 file changed, 77 insertions(+), 60 deletions(-) diff --git a/src/spaceone/core/model/mongo_model/__init__.py b/src/spaceone/core/model/mongo_model/__init__.py index efd2a42..5df06ef 100644 --- a/src/spaceone/core/model/mongo_model/__init__.py +++ b/src/spaceone/core/model/mongo_model/__init__.py @@ -479,7 +479,7 @@ def _make_condition(cls, condition): if operator not in FILTER_OPERATORS: raise ERROR_DB_QUERY( reason=f"Filter operator is not supported. (operator = " - f"{FILTER_OPERATORS.keys()})" + f"{FILTER_OPERATORS.keys()})" ) resolver, mongo_operator, is_multiple = FILTER_OPERATORS.get(operator) @@ -566,14 +566,14 @@ def _make_unwind_project_stage(only: list): @classmethod def _stat_with_unwind( - cls, - unwind: list, - only: list = None, - filter: list = None, - filter_or: list = None, - sort: list = None, - page: dict = None, - target: str = None, + cls, + unwind: list, + only: list = None, + filter: list = None, + filter_or: list = None, + sort: list = None, + page: dict = None, + target: str = None, ): if only is None: raise ERROR_DB_QUERY(reason="unwind option requires only option.") @@ -641,19 +641,19 @@ def _stat_with_unwind( @classmethod def query( - cls, - *args, - only=None, - exclude=None, - filter=None, - filter_or=None, - sort=None, - page=None, - minimal=False, - count_only=False, - unwind=None, - target=None, - **kwargs, + cls, + *args, + only=None, + exclude=None, + filter=None, + filter_or=None, + sort=None, + page=None, + minimal=False, + count_only=False, + unwind=None, + target=None, + **kwargs, ): filter = filter or [] filter_or = filter_or or [] @@ -715,7 +715,7 @@ def query( if start < 1: start = 1 - vos = vos[start - 1 : start + page["limit"] - 1] + vos = vos[start - 1: start + page["limit"] - 1] return vos, total_count @@ -786,7 +786,7 @@ def _make_sub_conditions(cls, sub_conditions, _before_group_keys): if operator not in _SUPPORTED_OPERATOR: raise ERROR_DB_QUERY( reason=f"'aggregate.group.fields.conditions.operator' condition's {operator} operator is not " - f"supported. (supported_operator = {_SUPPORTED_OPERATOR})" + f"supported. (supported_operator = {_SUPPORTED_OPERATOR})" ) if key in _before_group_keys: @@ -808,7 +808,7 @@ def _get_group_fields(cls, condition, _before_group_keys): if operator not in STAT_GROUP_OPERATORS: raise ERROR_DB_QUERY( reason=f"'aggregate.group.fields' condition's {operator} operator is not supported. " - f"(supported_operator = {list(STAT_GROUP_OPERATORS.keys())})" + f"(supported_operator = {list(STAT_GROUP_OPERATORS.keys())})" ) if name is None: @@ -927,7 +927,7 @@ def _get_project_fields(cls, condition): if operator and operator not in STAT_PROJECT_OPERATORS: raise ERROR_DB_QUERY( reason=f"'aggregate.project.fields' condition's {operator} operator is not supported. " - f"(supported_operator = {list(STAT_PROJECT_OPERATORS.keys())})" + f"(supported_operator = {list(STAT_PROJECT_OPERATORS.keys())})" ) if name is None: @@ -1085,9 +1085,9 @@ def _make_aggregate_rules(cls, aggregate): else: raise ERROR_REQUIRED_PARAMETER( key="aggregate.unwind or aggregate.group or " - "aggregate.count or aggregate.sort or " - "aggregate.project or aggregate.limit or " - "aggregate.skip" + "aggregate.count or aggregate.sort or " + "aggregate.project or aggregate.limit or " + "aggregate.skip" ) return _aggregate_rules @@ -1141,23 +1141,23 @@ def _stat_distinct(cls, vos, distinct, page): start = 1 result["total_count"] = len(values) - values = values[start - 1 : start + page["limit"] - 1] + values = values[start - 1: start + page["limit"] - 1] result["results"] = cls._make_distinct_values(values) return result @classmethod def stat( - cls, - *args, - aggregate=None, - distinct=None, - filter=None, - filter_or=None, - page=None, - target="SECONDARY_PREFERRED", - allow_disk_use=False, - **kwargs, + cls, + *args, + aggregate=None, + distinct=None, + filter=None, + filter_or=None, + page=None, + target="SECONDARY_PREFERRED", + allow_disk_use=False, + **kwargs, ): filter = filter or [] filter_or = filter_or or [] @@ -1195,8 +1195,25 @@ def _check_field_group(cls, field_group): @classmethod def _make_group_keys(cls, group_by, date_field, granularity=None): group_keys = [] - for key in group_by: - name = key.rsplit(".", 1)[-1:][0] + for group_option in group_by: + if isinstance(group_option, dict): + key = group_option.get("key") + name = group_option.get("name") + + if not (key and name): + raise ERROR_INVALID_PARAMETER( + key="group_by", + reason="group_by option requires a key and name.", + ) + elif isinstance(group_option, str): + key = group_option + name = key.rsplit(".", 1)[-1:][0] + else: + raise ERROR_INVALID_PARAMETER( + key="group_by", + reason="group_by option should be dict or str type.", + ) + group_keys.append({"key": key, "name": name}) if granularity and granularity in ["DAILY", "MONTHLY", "YEARLY"]: @@ -1436,24 +1453,24 @@ def _convert_date_value(cls, date_value, date_field_format): @classmethod def analyze( - cls, - *args, - granularity=None, - fields=None, - select=None, - group_by=None, - field_group=None, - filter=None, - filter_or=None, - page=None, - sort=None, - start=None, - end=None, - date_field="date", - date_field_format="%Y-%m-%d", - target="SECONDARY_PREFERRED", - allow_disk_use=False, - **kwargs, + cls, + *args, + granularity=None, + fields=None, + select=None, + group_by=None, + field_group=None, + filter=None, + filter_or=None, + page=None, + sort=None, + start=None, + end=None, + date_field="date", + date_field_format="%Y-%m-%d", + target="SECONDARY_PREFERRED", + allow_disk_use=False, + **kwargs, ): if fields is None: raise ERROR_REQUIRED_PARAMETER(key="fields") From d3c4c09e0157dcc4ae1ef4801248c891dfc3076a Mon Sep 17 00:00:00 2001 From: Jongmin Kim Date: Wed, 1 May 2024 21:29:40 +0900 Subject: [PATCH 2/2] fix: fix group_by option bug Signed-off-by: Jongmin Kim --- src/spaceone/core/model/mongo_model/__init__.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/spaceone/core/model/mongo_model/__init__.py b/src/spaceone/core/model/mongo_model/__init__.py index 5df06ef..52ec474 100644 --- a/src/spaceone/core/model/mongo_model/__init__.py +++ b/src/spaceone/core/model/mongo_model/__init__.py @@ -1266,9 +1266,9 @@ def _check_condition(cls, condition): @classmethod def _make_field_group_keys(cls, group_keys, field_group): field_group_keys = [] - for group_key in group_keys: - key = group_key["key"].rsplit(".", 1)[-1:][0] - name = group_key["name"] + for group_option in group_keys: + key = group_option["name"] + name = group_option["name"] if name not in field_group: if name == "date": field_group_keys.append({"key": "date", "name": "date"})