这是在实现多表关联时想到的。
我们现在这套体系,实现多表关联比较复杂。如果Superset能官方支持多表关联,不知道会是什么样的方案,复杂度如何。
- 在公式这个层面,没有关联条件,只有两个列、或者多个列,相互之间该如何计算(+-*/)。
->由此可知,在展开公式之前,结果集要先进行join,以保证列计算时,每一行被正确的对齐了。
->查找基础KPI、分组、查询的操作不需要改变。在获取df之后,merge各个df,要提前到展开公式之前。
- 如果没有定义join条件呢?
join是在结果集层面定义的,两个结果集如何关联起来。
如果查询的结果集是单结果集,完全不影响在公式里引用来自其他结果集的KPI,这个时候是没有join条件的。
--在程序中,要把这种情况当成错误来处理,即,KPI公式中出现的其他KPI,不能来自join定义之外。
->在逐层嵌套的KPI定义体系中,可能存在需要到本层join定义之外,再去下层获取join条件的情况(假设KPI有4层,第1层的join条件,很可能无法把第4层的数据集关联起来)。所以,join条件也需要迭代处理。每一层都需要join操作。
- 当前的策略是独立查询各个table的数据,关联条件作用在pandas.DataFrame之间,每个DataFrame中可能包含不需要的数据,即,不满足join条件的数据也可能会被加载到DataFrame中。再考虑到每个查询中limit的存在,会有部分满足条件的数据不会出现在join之后的结果集中。
--这个问题没找到完善的解决方案
- pandas的merge行成一个独立的DataFrame,存在列名重复的可能。
--参见这个讨论:https://stackoverflow.com/questions/19125091/pandas-merge-how-to-avoid-duplicating-columns
--来自两个DataFrame的列如果重名,可以用suffixes函数控制列名加什么后缀。
--https://blog.csdn.net/brucewong0516/article/details/82707492
--所以,这个问题至少是可以解决的。
- 过滤条件(如果有的话),应该和join一起处理。
细节待定
展开公式的逻辑
->从KPI到换算成列
2019-08-06补充:
- Context
写二叉树代码的时候,就在想,拼接公式时要不要加一个上下文。
今早模糊想到,的确需要一个上下文(Context)。拼接公式是从叶子节点开始,如果叶子节点是KPI,要查到对应的KPI属于哪个数据集,一旦涉及两个或多个KPI之间的运算,就有可能需要join才能计算,否则,不对齐的行之间运算没有意义。
join之后呢,就需要有个地方保存这个join出来的数据集,而且,还要供公式树上的上一级节点使用。
假设有Dataset_1/Dataset_2/Dataset_3三个数据集。
Dataset_1 : 『KPI_1/KPI_2/KPI_3』
Dataset_2 : 『KPI_4/KPI_5』
Dataset_3 : 『KPI_6/KPI_7』
KPI_2 = KPI_5 + KPI_7
KPI_3 = KPI_6 + KPI_7
对KPI_3来说,KPI_6/KPI_7属于同一个数据集,不需要先join再计算。
对KPI_2来说,KPI_5/KPI_7不属于同一个数据集,需要先join Dataset_2、Dataset_2再计算,否则两个数据集的行没对齐,计算得到的结果没有实际意义。
公式展开的过程,就是计算得到pandas.core.series.Series的过程;同一个数据集的各个KPI即是多个pandas.core.series.Series,数据集是pandas.core.series.Series的集合,也就是一个pandas.DataFrame。
对完全由公式KPI构成的数据集,遍历KPI,展开公式,就是计算Series,保存到DataFrame。即,在查询数据时,一个数据集,和一个DataFrame对应。
把Series加到DataFrame,可以参考:https://stackoverflow.com/questions/12555323/adding-new-column-to-existing-dataframe-in-python-pandas
见joaquin的回答,2017年更新的方法,是调用assign,把Series加入到DataFrame。
2019-08-08补充:如果需要动态命名新增列,可以参考 https://stackoverflow.com/questions/39767718/pandas-assign-with-new-column-name-as-string
--从2019年3月开始重新做Superset二次开发,快五个月了,像是把2017年想要实现但没条件实现的功能,都实现了。是不是又要告一段落了呢?