标签生效逻辑

This commit is contained in:
Àî×ÚÕñ 2022-07-07 15:56:41 +08:00
parent de39d145aa
commit 49c7668169
4 changed files with 393 additions and 140 deletions

View File

@ -616,16 +616,29 @@ async def retention_model(request: Request,
tmp['n_outflow'].append(v[f'on{i}'])
tmp = summary_values['均值']
retention_avg_dict = {}
group_label = res['group_label']
# 多个分组项时,合成列表返回
if len(groupby)>1:
if not group_label:
if len(groupby) > 1:
summary_valuess = {}
for k, v in summary_values.items():
if 'str' in str(type(k)):
summary_valuess[str([k])] = v
else:
summary_valuess[str(list(k))] = v
else:
summary_valuess=summary_values
summary_valuess = summary_values
# 包含标签分组项
else:
summary_valuess = {}
for k, v in summary_values.items():
key = list(k)
# 增加标签分组到对应的key里面
for name, index in group_label.items():
key.insert(index, name)
summary_valuess[str(key)] = v
for rn in retention_n:
for rt, rd in df.T.items():
@ -1436,26 +1449,29 @@ async def scatter_model(
event_type = analysis.events[0]['eventName']
where = analysis.events[-1]['quotaname']
sql = res['sql']
columnName = analysis.event_view['groupBy'][-1]['columnName']
if analysis.event_view['groupBy'] != []:
if columnName != '':
#按天分组
sql = sql.replace(f'toDate(addHours({game}.event."#event_time", 8)) AS date', f'`{columnName}` as va',
1)
sql = sql.replace(f'toDate(addHours({game}.event."#event_time", 8))', f'`{columnName}`', 1)
#按周分组
sql = sql.replace(f'toStartOfWeek(addHours({game}.event."#event_time", 8)) AS date', f'`{columnName}` as va',
1)
sql = sql.replace(f'toStartOfWeek(addHours({game}.event."#event_time", 8))', f'`{columnName}`', 1)
#按月分组
sql = sql.replace(f'toStartOfMonth(addHours({game}.event."#event_time", 8)) AS date', f'`{columnName}` as va',
1)
sql = sql.replace(f'toStartOfMonth(addHours({game}.event."#event_time", 8))', f'`{columnName}`', 1)
#合计
if analysis.event_view.get('timeParticleSize') == "total":
sql = sql.replace(f'SELECT', f'SELECT `{columnName}` as va,', 1)
print(sql)
group_by = analysis.event_view['groupBy']
# 排除标签
true_group = [i for i in group_by if i['data_type'] != "user_label"]
columnName = true_group[-1]['columnName']
if true_group != []:
# if columnName != '':
# # 按天分组
# sql = sql.replace(f'toDate(addHours({game}.event."#event_time", 8)) AS date', f'`{columnName}` as va',
# 1)
# sql = sql.replace(f'toDate(addHours({game}.event."#event_time", 8))', columnName, 1)
# # 按周分组
# sql = sql.replace(f'toStartOfWeek(addHours({game}.event."#event_time", 8)) AS date',
# f'`{columnName}` as va',
# 1)
# sql = sql.replace(f'toStartOfWeek(addHours({game}.event."#event_time", 8))', columnName, 1)
# # 按月分组
# sql = sql.replace(f'toStartOfMonth(addHours({game}.event."#event_time", 8)) AS date',
# f'`{columnName}` as va',
# 1)
# sql = sql.replace(f'toStartOfMonth(addHours({game}.event."#event_time", 8))', columnName, 1)
# # 合计
# if analysis.event_view.get('timeParticleSize') == "total":
# sql = sql.replace(f'SELECT', f'SELECT {columnName} as va,', 1)
df = await ckdb.query_dataframe(sql)
if df.empty:
return schemas.Msg(code=-9, msg='无数据', data=None)
@ -1472,6 +1488,8 @@ async def scatter_model(
interval_type = res['interval_type']
analysi = res['analysis']
groupby = res['groupby']
true_df = df.groupby(groupby).sum()
group_label = res['group_label']
quota_interval_arr = res['quota_interval_arr']
# 兼容合计的
# if res['time_particle'] == 'total':
@ -1480,20 +1498,25 @@ async def scatter_model(
if analysi != 'number_of_days' and interval_type != 'discrete':
# 默认区间
max_v = int(df['values'].max())
min_v = int(df['values'].min())
max_v = int(true_df['values'].max())
min_v = int(true_df['values'].min())
interval = (max_v - min_v) // 10 or 1
resp = {'list': dict(),
'start_date': res['start_date'],
'end_date': res['end_date'],
'time_particle': res['time_particle'],
'biaotou': columnName
'biaotou': groupby
}
if 'float' in str(df.dtypes['va']):
df['va'] = df['va'].astype(int)
if 'list' in str(type(df['va'][0])):
f = lambda x: x[0]
df['va'] = df['va'].map(f)
# if 'float' in str(df.dtypes['va']):
# df['va'] = df['va'].astype(int)
# for index, gi in enumerate(groupby):
# resp['list'][str(index)] = dict()
# if 'float' in str(df.dtypes[gi]):
# df[gi] = df[gi].astype(int)
# if 'list' in str(type(df[gi][0])):
# f = lambda x: x[0]
# df[gi] = df[gi].map(f)
if not quota_interval_arr:
resp['label'] = [f'[{i},{i + interval})' for i in range(min_v, max_v, interval)]
bins = [i for i in range(min_v, max_v + interval, interval)]
@ -1510,12 +1533,19 @@ async def scatter_model(
# f = lambda x: x[0]
# df['va'] = df['va'].map(f)
# 这是分组的
for key, tmp_df in df.groupby('va'):
for key, tmp_df in true_df.groupby(groupby):
bins_s = pd.cut(tmp_df['values'], bins=bins,
right=True, include_lowest=True).value_counts()
bins_s.sort_index(inplace=True)
total = int(bins_s.sum())
if group_label:
if isinstance(key, str):
key = [key]
key = list(key)
for name, idx in group_label.items():
key.insert(idx, name)
key = str(key)
if res['time_particle'] == 'total111':
resp['list']['合计'] = dict()
@ -1528,32 +1558,36 @@ async def scatter_model(
if str(p[i]) == 'nan':
p[i] = 0
# 映射对应的埋点数据
re = await crud.select_map.get_list(db, game)
re_list = [i['attr_name'] for i in re]
if columnName in re_list:
for i in re:
if columnName == i['attr_name']:
for datas in i['map_']:
if key == datas['id']:
key = datas['title']
break
break
if 'time' not in columnName:
resp['list'][key] = dict()
resp['list'][key] = {'n': bins_s.to_list(), 'total': total,
'p': [str(i) + '%' for i in p],
'title': '总体'}
else:
resp['list'][key.strftime('%Y-%m-%d %H:%M:%S')] = dict()
resp['list'][key.strftime('%Y-%m-%d %H:%M:%S')] = {'n': bins_s.to_list(), 'total': total,
# re = await crud.select_map.get_list(db, game)
# re_list = [i['attr_name'] for i in re]
# if gi in re_list:
# for i in re:
# if gi == i['attr_name']:
# for datas in i['map_']:
# if key == datas['id']:
# key = datas['title']
# break
# break
# if 'time' not in groupby:
resp['list'][str(key)] = dict()
resp['list'][str(key)] = {'n': bins_s.to_list(), 'total': total,
'p': [str(i) + '%' for i in p],
'title': '总体'}
# else:
# resp['list'][key.strftime('%Y-%m-%d %H:%M:%S')] = dict()
# resp['list'][key.strftime('%Y-%m-%d %H:%M:%S')] = {'n': bins_s.to_list(), 'total': total,
# 'p': [str(i) + '%' for i in p],
# 'title': '总体'}
# 兼容下载功能
download = analysis.event_view.get('download', '')
if download == 1:
create_df = create_neidf(resp, columnName)
Download = Download_xlsx(create_df, '分布分析')
return Download
if group_label:
for name, idx in group_label.items():
resp['biaotou'].insert(idx, name)
return schemas.Msg(code=0, msg='ok', data=resp)
else:
# 离散数字
@ -1561,15 +1595,17 @@ async def scatter_model(
'start_date': res['start_date'],
'end_date': res['end_date'],
'time_particle': res['time_particle'],
'biaotou': columnName
'biaotou': groupby
}
labels = [str(i) for i in sorted(df['values'].unique())]
labels = [str(i) for i in sorted(true_df['values'].unique())]
resp['label'] = labels
if 'list' in str(type(df['va'][0])):
f = lambda x: x[0]
df['va'] = df['va'].map(f)
# for index, gi in enumerate(groupby):
# resp['list'][str(index)] = dict()
# if 'list' in str(type(df[gi][0])):
# f = lambda x: x[0]
# df[gi] = df[gi].map(f)
shaixuan = analysis.events[0].get('analysis')
for key, tmp_df in df.groupby(['va']):
for key, tmp_df in true_df.groupby(groupby):
if shaixuan == 'uniqExact':
total = len(set(tmp_df['uid']))
else:
@ -1578,20 +1614,28 @@ async def scatter_model(
dt = '合计'
else:
# 映射对应的埋点数据
re = await crud.select_map.get_list(db, game)
re_list = [i['attr_name'] for i in re]
if columnName in re_list:
for i in re:
if columnName == i['attr_name']:
for datas in i['map_']:
if key == datas['id']:
key = datas['title']
break
break
# re = await crud.select_map.get_list(db, game)
# re_list = [i['attr_name'] for i in re]
# if gi in re_list:
# for i in re:
# if gi == i['attr_name']:
# for datas in i['map_']:
# if key == datas['id']:
# key = datas['title']
# break
# break
dt = key
# dt = key.strftime('%Y-%m-%d')
# dt='合计'
# 存在标签分组
if group_label:
if isinstance(dt, str):
dt = [dt]
dt = list(dt)
for name, idx in group_label.items():
dt.insert(idx, name)
dt = str(dt)
labels_dict = {}
for key2, tmp_df2 in tmp_df.groupby('values'):
label = str(key2)
@ -1618,7 +1662,7 @@ async def scatter_model(
number_str = str(number_int) + '%'
list_p.append(number_str)
resp['list'][dt] = {'n': [labels_dict01.get(i, 0) for i in labels], 'total': total,
resp['list'][str(dt)] = {'n': [labels_dict01.get(i, 0) for i in labels], 'total': total,
'p': list_p}
else:
list_p = []
@ -1626,7 +1670,7 @@ async def scatter_model(
number_int = round(labels_dict.get(i, 0) * 100 / total, 2)
number_str = str(number_int) + '%'
list_p.append(number_str)
resp['list'][dt] = {'n': [labels_dict.get(i, 0) for i in labels], 'total': total,
resp['list'][str(dt)] = {'n': [labels_dict.get(i, 0) for i in labels], 'total': total,
'p': list_p}
# resp['list'][dt] = {'总体': {'n': [labels_dict.get(i, 0) for i in labels], 'total': total,
# 'p': [round(labels_dict.get(i, 0) * 100 / total, 2) for i in labels]}}
@ -1641,6 +1685,10 @@ async def scatter_model(
create_df = create_neidf(resp, columnName)
Download = Download_xlsx(create_df, '分布分析')
return Download
if group_label:
for name, idx in group_label.items():
resp['biaotou'].insert(idx, name)
return schemas.Msg(code=0, msg='ok', data=resp)
else:
return schemas.Msg(code=-9, msg='没有添加分组项', data='')

View File

@ -51,34 +51,34 @@ async def ltv_model_sql(
) -> schemas.Msg:
""" ltv模型sql """
await analysis.init(data_where=current_user.data_where)
res = analysis.ltv_model_sql()
sql = res['sql']
res = await analysis.ltv_model_sql()
sql = res['sql'].replace('/n','').replace('[','').replace(']','')
#仅一条筛选条件则是把GM过滤后获取全部数据
if len(analysis.global_filters)==1 and analysis.global_filters[0]['strftv']=='GM':
# if len(analysis.global_filters)==1 and analysis.global_filters[0]['strftv']=='GM':
try:
df = await ckdb.query_dataframe(sql)
except Exception as e:
return schemas.Msg(code=-9, msg='报表配置参数异常')
#多条筛选条件则合成新的sql
else:
new_sql=""""""
#拆分sql
split_sql = sql.split('AND 1')
#获取每一条筛选条件
for i in analysis.global_filters:
#剔除GM
if i['strftv'] != 'GM':
#获取筛选条件的包含关系
bijiao=get_bijiao(i["comparator"])
#获取筛选条件的值
condition=tuple(i['ftv'])
#获取事件名
columnName=i['columnName']
dd = f""" AND {game}.event.{columnName} {bijiao} {condition}"""
new_sql+=dd
split_="""AND 1 """
news_sql = split_sql[0] + split_+new_sql + split_sql[1] + split_+new_sql+ split_sql[2]+split_+split_sql[3]
df = await ckdb.query_dataframe(news_sql)
# else:
# new_sql=""""""
# #拆分sql
# split_sql = sql.split('AND 1')
# #获取每一条筛选条件
# for i in analysis.global_filters:
# #剔除GM
# if i['strftv'] != 'GM':
# #获取筛选条件的包含关系
# bijiao=get_bijiao(i["comparator"])
# #获取筛选条件的值
# condition=tuple(i['ftv'])
# #获取事件名
# columnName=i['columnName']
# dd = f""" AND {game}.event.{columnName} {bijiao} {condition}"""
# new_sql+=dd
# split_="""AND 1 """
# news_sql = split_sql[0] + split_+new_sql + split_sql[1] + split_+new_sql+ split_sql[2]+split_+split_sql[3]
# df = await ckdb.query_dataframe(news_sql)
# # 判断11月23号之前的数据
# list_data_range=analysis.date_range
# liststr_data_range=[]
@ -248,6 +248,7 @@ async def ltv_model_sql(
return schemas.Msg(code=0, msg='ok', data=data)
@router.post("/ltv_model_export")
async def ltv_model_export(request: Request,
game: str,

View File

@ -1,6 +1,6 @@
import re
from typing import Tuple
from copy import deepcopy
import arrow
import sqlalchemy as sa
import json
@ -196,14 +196,24 @@ class BehaviorAnalysis:
if item['data_type'] == 'user_label':
item.update({
'comparator': "in",
'comparator_name': ""
'comparator_name': "",
'tableType': "user_label"
})
# 加入分组标签
self.group_label.update({item['columnDesc']: idx})
# 事件分析,分布分析
if self.event_view['cksql'] in ['event', 'scatter']:
# 加入events中每个event的filts条件中
if self.events:
for i in self.events:
i['filts'].append(item)
# 留存分析,漏斗分析
if self.event_view['cksql'] in ['retention', 'funnel']:
# 加入全局删选filts条件中
self.event_view['filts'].append(item)
continue
# 不是标签加入分组项中
res.append(getattr(self.event_tbl.c, item['columnName']))
@ -230,7 +240,29 @@ class BehaviorAnalysis:
return start_date, end_date, date_range
def _get_global_filters(self):
return self.event_view.get('filts') or []
_res = []
if self.event_view.get('filts'):
_res = self.event_view.get('filts')
# 漏斗分析,特殊处理
if self.event_view['cksql'] in ['funnel']:
_trueRes = []
for i in _res:
if 'comparator' in i:
trueI = deepcopy(i)
_trueRes.append(trueI)
continue
comparator = i.pop('comparator_id')
comparatorName = i.pop('comparator_name')
i.update({
'comparator': comparator,
'comparatorName': comparatorName,
'tableType': "user_label"
})
trueI = deepcopy(i)
_trueRes.append(trueI)
_res = _trueRes
return _res
async def _init_table(self):
"""
@ -248,6 +280,87 @@ class BehaviorAnalysis:
# self.event_tbl = sa.Table('event_view', metadata, *[sa.Column(column) for column in columns])
self.event_tbl = sa.Table('event', metadata, *[sa.Column(column) for column in columns])
async def handler_trace_filts(self, *filters):
"""
:param filters: (filts:list,relation:str)
:param g_f:
:param relation:
:return:
"""
user_filters = []
event_filters = []
for filter in filters:
user_filter = []
event_filter = []
for item in filter:
comparator = item['comparator_id']
if item['tableType'] == 'user':
where = user_filter
elif item['tableType'] == 'event':
where = event_filter
elif item['tableType'] == 'user_label':
user_cluster_def = UserClusterDef(self.game, item['columnName'], self.data_where)
await user_cluster_def.init()
sub_qry = user_cluster_def.to_sql_qry()
if comparator == 'in':
event_filter.append(sa.Column('#account_id').in_(sub_qry))
else:
event_filter.append(sa.Column('#account_id').notin_(sub_qry))
continue
else:
continue
tbl = getattr(self, f'{item["tableType"]}_tbl')
col = getattr(tbl.c, item['columnName'])
# 日期类型处理时区
if item.get('data_type') == 'datetime':
col = func.addHours(col, self.zone_time)
ftv = item['ftv']
if comparator == '==':
if len(ftv) > 1:
where.append(or_(*[col == v for v in ftv]))
else:
where.append(col == ftv[0])
elif comparator == '>=':
where.append(col >= ftv[0])
elif comparator == '<=':
where.append(col <= ftv[0])
elif comparator == '>':
where.append(col > ftv[0])
elif comparator == '<':
where.append(col < ftv[0])
elif comparator == 'range':
where.append(col > ftv[0])
where.append(col <= ftv[1])
elif comparator == 'is not null':
where.append(col.isnot(None))
elif comparator == 'is null':
where.append(col.is_(None))
elif comparator == 'like':
where.append(col.like(f'%{ftv[0]}%'))
elif comparator == 'not like':
where.append(col.notlike(f'%{ftv[0]}%'))
elif comparator == 'in':
where.append(col.in_(ftv))
elif comparator == '!=':
where.append(col != ftv[0])
else:
if event_filter:
event_filters.append(and_(*event_filter))
if user_filter:
user_filters.append(and_(*user_filter))
return event_filters, user_filters
async def handler_filts(self, *filters):
"""
@ -684,6 +797,7 @@ ORDER BY level
sql = sql.replace('_windows_gap_', f"({windows_gap})")
print(sql)
return {'sql': sql,
'group_label': self.group_label,
'groupby': [i.key for i in self.groupby],
'date_range': self.date_range,
'cond_level': cond_level,
@ -773,6 +887,7 @@ ORDER BY level
print(sql)
return {
'sql': sql,
'group_label': self.group_label,
'interval_type': event['intervalType'],
'analysis': analysis,
'quota_interval_arr': quota_interval_arr,
@ -815,6 +930,7 @@ ORDER BY level
print(sql)
return {
'sql': sql,
'group_label': self.group_label,
'interval_type': event['intervalType'],
'analysis': analysis,
'quota_interval_arr': quota_interval_arr,
@ -837,17 +953,19 @@ ORDER BY level
event_names = self.events.get('event_names')
source_event = self.events.get('source_event', {}).get('eventName')
source_type = self.events.get('source_event', {}).get('source_type')
wheres = self.events['user_filter']['filts']
sql_one=''
if wheres != []: # 有筛选条件的时候使用
columnName=wheres[0]['columnName'] # 获取字段名
event=await get_event(columnName,self.game) # 获取字段属于那个事件,或者是否是基础属性
if event == '基础属性':
sql_one=f""" and `{columnName}` {wheres[0]['comparator']} '{wheres[0]['ftv'][0]}' and `#event_name` in evnet_all) """
else:# 如果包含有事件则进入下面的逻辑
sql_one=f"""and `#account_id` in ( SELECT `#account_id` FROM {self.game}.event WHERE `#event_name`= '{event}' and `{columnName}` =
'{wheres[0]['ftv'][0]}' and addHours(`#event_time`, {self.zone_time}) >= start_data
and addHours(`#event_time`, {self.zone_time}) <= end_data ) and `#event_name` in evnet_all)"""
filters = self.events.get('user_filter', {}).get('filts', [])
event_filter, user_filter = await self.handler_trace_filts(filters)
where_a = '1'
if event_filter:
qry = sa.select().where(*event_filter)
sql = str(qry.compile(compile_kwargs={"literal_binds": True}))
where_a = 'WHERE '.join(sql.split('WHERE ')[1:])
where_b = '1'
if user_filter:
qry = sa.select().where(*user_filter)
sql = str(qry.compile(compile_kwargs={"literal_binds": True}))
where_b = sql.split('WHERE ')[1]
sql_a = f"""with
'{source_event}' as start_event,
{tuple(event_names)} as evnet_all,
@ -889,7 +1007,10 @@ from (with
group by `#account_id`
HAVING has_midway_hit = 1
)
where arrayElement(event_chain, 1) = start_event
where arrayElement(event_chain, 1) = start_event and {where_a} and "#account_id" IN (SELECT "#account_id"
FROM (SELECT "#account_id"
FROM {self.game}.user_view
WHERE {where_b}) AS anon_b)
GROUP BY event_chain,`#account_id`
ORDER BY values desc
"""
@ -933,13 +1054,14 @@ from (with
group by `#account_id`
HAVING has_midway_hit = 1
)
where arrayElement(event_chain, -1) = end_event
where arrayElement(event_chain, -1) = end_event and {where_a} and "#account_id" IN (SELECT "#account_id"
FROM (SELECT "#account_id"
FROM {self.game}.user_view
WHERE {where_b}) AS anon_b)
GROUP BY event_chain,`#account_id`
ORDER BY values desc"""
sql = sql_a if source_type == 'initial_event' else sql_b
if sql_one != '':
sql= sql.replace('and `#event_name` in evnet_all)',sql_one,1)
print(sql)
return {
'sql': sql,

View File

@ -14,9 +14,8 @@ import crud
import schemas
from core.config import settings
from db import get_database
from db.redisdb import get_redis_pool, RedisDrive
from models.user_label import UserClusterDef
from utils import get_event
from db.redisdb import get_redis_pool, RedisDrive
class XAnalysis:
@ -25,20 +24,28 @@ class XAnalysis:
self.game = game
self.event_view = dict()
self.events = []
self.zone_time: int = 0
self.global_filters = []
self.account_filters = []
self.global_relation = 'and'
self.date_range = []
self.ext_filters = (self.data_in.ext_filter.get('filts', []), self.data_in.ext_filter.get('relation', 'and'))
self.start_date = None
self.end_date = None
self.data_where=[]
self.event_tbl=None
self.zone_time:int = 0
def _get_global_filters(self):
return self.event_view.get('filts') or [] #获取event_view字典里面filts的值或返回空列表
_res = self.event_view.get('filts', [])
if _res:
for idx, item in enumerate(_res):
if item['data_type'] == 'user_label':
_res[idx].update({
'tableType': item['data_type'],
})
else:
_res[idx].update({
'tableType': item['table_type'],
})
return _res # 获取event_view字典里面filts的值或返回空列表
async def init(self, *args, **kwargs):
if self.data_in.report_id:
@ -70,8 +77,69 @@ class XAnalysis:
if 'data_where' in kwargs:
self.account_filters = kwargs['data_where'].get(self.game, [])
def handler_filts(self, *filters):
# def handler_filts(self, *filters):
# """
# :param filters: (filts:list,relation:str)
# :param g_f:
# :param relation:
# :return:
# """
#
# event_filters = []
# for filter in filters:
# filts = filter[0]
# relation = filter[1]
# event_filter = []
# for item in filts:
#
# where = event_filter
#
# col = sa.Column(item['columnName'])
#
# comparator = item['comparator']
# ftv = item['ftv']
# if comparator == '==':
# if len(ftv) > 1:
# where.append(or_(*[col == v for v in ftv]))
# else:
# where.append(col == ftv[0])
# elif comparator == '>=':
# where.append(col >= ftv[0])
# elif comparator == '<=':
# where.append(col <= ftv[0])
# elif comparator == '>':
# where.append(col > ftv[0])
# elif comparator == '<':
# where.append(col < ftv[0])
#
# elif comparator == 'is not null':
# where.append(col.isnot(None))
# elif comparator == 'is null':
# where.append(col.is_(None))
#
# elif comparator == 'like':
# where.append(col.like(f'%{ftv[0]}%'))
#
# elif comparator == 'not like':
# where.append(col.notlike(f'%{ftv[0]}%'))
#
# elif comparator == 'in':
# where.append(col.in_(ftv))
#
# elif comparator == '!=':
# where.append(col != ftv[0])
# if relation == 'and':
# if event_filter:
# event_filters.append(and_(*event_filter))
# else:
# if event_filter:
# event_filters.append(or_(*event_filter))
#
# return event_filters
async def handler_filts(self, *filters):
"""
:param filters: (filts:list,relation:str)
:param g_f:
:param relation:
@ -82,10 +150,26 @@ class XAnalysis:
for filter in filters:
filts = filter[0]
relation = filter[1]
user_filter = []
event_filter = []
for item in filts:
comparator = item['comparator']
if item['tableType'] == 'user':
where = user_filter
elif item['tableType'] == 'event':
where = event_filter
elif item['tableType'] == 'user_label':
user_cluster_def = UserClusterDef(self.game, item['columnName'], self.account_filters)
await user_cluster_def.init()
sub_qry = user_cluster_def.to_sql_qry()
if comparator == 'in':
event_filter.append(sa.Column('#account_id').in_(sub_qry))
else:
event_filter.append(sa.Column('#account_id').notin_(sub_qry))
continue
else:
continue
col = sa.Column(item['columnName'])
@ -130,8 +214,7 @@ class XAnalysis:
return event_filters
def ltv_model_sql(self):
# ltv的生成sql
async def ltv_model_sql(self):
days = (arrow.get(self.event_view['endTime']).date() - arrow.get(self.event_view['startTime']).date()).days
quota = self.event_view['quota']
select_ltv = []
@ -163,17 +246,16 @@ class XAnalysis:
sql = str(qry.compile(compile_kwargs={"literal_binds": True}))
where_str = sql.split('WHERE ')[1]
where_order = self.handler_filts((self.global_filters, self.global_relation)) #global_relation就是 and
where_order = await self.handler_filts((self.global_filters, self.global_relation)) # global_relation就是 and
where_order_str = 1
if where_order:
qry = sa.select().where(*where_order)
sql = str(qry.compile(compile_kwargs={"literal_binds": True}))
where_order_str = sql.split('WHERE ')[1]
where_order_str = 'WHERE '.join(sql.split('WHERE ')[1:])
where_account = self.handler_filts((self.account_filters, 'and'), self.ext_filters)
where_account = await self.handler_filts((self.account_filters, 'and'), self.ext_filters)
where_account_str = 1
if where_account:
qry = sa.select().where(*where_account)
sql = str(qry.compile(compile_kwargs={"literal_binds": True}))
where_account_str = sql.split('WHERE ')[1]