From c92be39e492697fbfe6ebe4194e7b1e6b44eaacd Mon Sep 17 00:00:00 2001 From: wuaho Date: Mon, 2 Aug 2021 11:25:09 +0800 Subject: [PATCH] =?UTF-8?q?=E5=85=AC=E5=BC=8F=E8=A7=A3=E6=9E=90=E7=B1=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/api_v1/endpoints/query.py | 3 +- core/config.py | 2 +- models/behavior_analysis.py | 104 +++++++++++++++++++++------------- 3 files changed, 67 insertions(+), 42 deletions(-) diff --git a/api/api_v1/endpoints/query.py b/api/api_v1/endpoints/query.py index bea3ba5..43d579d 100644 --- a/api/api_v1/endpoints/query.py +++ b/api/api_v1/endpoints/query.py @@ -74,7 +74,8 @@ async def event_model( df = await ckdb.query_dataframe(sql) df.fillna(0,inplace=True) if df.shape[0] == 0: - return schemas.Msg(code=0, msg='ok', data=[q]) + continue + # return schemas.Msg(code=0, msg='ok', data=[q]) if groupby: # 有分组 diff --git a/core/config.py b/core/config.py index a04b493..e644601 100644 --- a/core/config.py +++ b/core/config.py @@ -247,7 +247,7 @@ class Settings(BaseSettings): ARITHMETIC = { '+': lambda x, y: x + y, '-': lambda x, y: x - y, - 'x': lambda x, y: x * y, + '*': lambda x, y: x * y, '/': lambda x, y: x / y, } diff --git a/models/behavior_analysis.py b/models/behavior_analysis.py index 4359f88..c77f3d1 100644 --- a/models/behavior_analysis.py +++ b/models/behavior_analysis.py @@ -1,3 +1,4 @@ +import re from typing import Tuple import arrow @@ -18,6 +19,68 @@ from db import get_database from db.redisdb import get_redis_pool, RedisDrive +class CustomEvent: + def __init__(self, tbl, string, format): + self.tbl = tbl + self.string = string + self.pattern = re.compile('[+\-*/]') + self.format = format + self.events_name = [] + + def _parse(self, s): + m = s.split('.') + if len(m) == 3: + event_name, attr, comp = m + self.events_name.append(event_name) + return getattr(func, comp)(getattr(func, 'if')(getattr(self.tbl.c, '#event_name') == event_name, + getattr(self.tbl.c, attr), 0)) + elif len(m) == 2: + event_name, comp = m + self.events_name.append(event_name) + # 总次数 + if comp == 'total_count': + return func.sum(getattr(func, 'if')(getattr(self.tbl.c, '#event_name') == event_name, 1, 0)) + elif comp == 'touch_user_count': + return func.uniqCombined(getattr(func, 'if')(getattr(self.tbl.c, '#event_name') == event_name, + getattr(self.tbl.c, '#account_id'), None)) + elif comp == 'touch_user_avg': + return func.divide( + func.sum(getattr(func, 'if')(getattr(self.tbl.c, '#event_name') == event_name, 1, 0)), + func.uniqCombined(getattr(func, 'if')(getattr(self.tbl.c, '#event_name') == event_name, + getattr(self.tbl.c, '#account_id'), None))) + elif len(m) == 1: + n = int(m[0]) + return n + + def str2obj(self, factors, opts): + sel = None + for i, factor in enumerate(factors): + if i == 0: + sel = self._parse(factor) + else: + tmp = self._parse(factor) + sel = settings.ARITHMETIC[opts[i - 1]](sel, tmp) + return sel + + def parse(self): + factors = self.pattern.split(self.string) + opts = self.pattern.findall(self.string) + sel = self.str2obj(factors, opts) + decimal = 2 + if self.format == 'percent': + sel = sel * 100 + elif format == 'integer': + decimal = 0 + elif format == 'float': + decimal = 2 + sel = func.round(sel, decimal).label('values') + res = { + 'event_name': self.events_name, + 'select': sel + } + return res + + class BehaviorAnalysis: def __init__(self, game: str, data_in: schemas.CkQuery, rdb: RedisDrive = Depends(get_redis_pool)): self.game = game @@ -198,45 +261,6 @@ class BehaviorAnalysis: 'unit_num': self.unit_num } - def custom_event(self, s, format='float'): - def f(m): - if len(m) == 3: - event_name, attr, comp = m - return getattr(func, comp)(getattr(func, 'if')(getattr(self.event_tbl.c, '#event_name') == event_name, - getattr(self.event_tbl.c, attr), 0)) - elif len(m) == 2: - event_name, comp = m - # 总次数 - if comp == 'total_count': - return func.sum(getattr(func, 'if')(getattr(self.event_tbl.c, '#event_name') == event_name, 1, 0)) - elif comp == 'touch_user_count': - return func.uniqCombined(getattr(func, 'if')(getattr(self.event_tbl.c, '#event_name') == event_name, - getattr(self.event_tbl.c, '#account_id'), None)) - elif comp == 'touch_user_avg': - return func.divide( - func.sum(getattr(func, 'if')(getattr(self.event_tbl.c, '#event_name') == event_name, 1, 0)), - func.uniqCombined(getattr(func, 'if')(getattr(self.event_tbl.c, '#event_name') == event_name, - getattr(self.event_tbl.c, '#account_id'), None))) - - opt = ({'+', '-', '*', '/'} & set(s)).pop() - a, b = s.split(opt) - r1 = a.split('.') - n = 1 - decimal = 2 - if format == 'percent': - n = 100 - elif format == 'integer': - decimal = 0 - if '.' in b: - r2 = b.split('.') - return {'event_name': [r1[0], r2[0]], - 'select': func.round(settings.ARITHMETIC[opt](f(r1) * n, f(r2)), decimal).label('values') - } - elif b.isdigit(): - return {'event_name': [r1[0]], - 'select': func.round(settings.ARITHMETIC[opt](f(r1) * n, int(b)), decimal).label('values') - } - def event_model_sql(self): sqls = [] event_time_col = getattr(self.event_tbl.c, '#event_time') @@ -255,7 +279,7 @@ class BehaviorAnalysis: if event.get('customEvent'): formula = event.get('customEvent') - custom = self.custom_event(formula, format) + custom = CustomEvent(self.event_tbl, formula, format).parse() event_name = custom['event_name'] where = [event_name_col.in_(event_name)] event_filter, _ = self.handler_filts(*event['filts'])