公式解析类
This commit is contained in:
parent
6e36de0889
commit
c92be39e49
@ -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:
|
||||
# 有分组
|
||||
|
@ -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,
|
||||
}
|
||||
|
||||
|
@ -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'])
|
||||
|
Loading…
Reference in New Issue
Block a user