count left join很慢_生成join语句的函数(开发过程记录,不包括业务介绍,没什么参考价值)...

v2-a45ccf1024425058f54dbd2d48237087_1440w.jpg?source=172ae18b

Superset查询数据用了SQLAlchemy的两种接口。

一种是带模型定义的,像Dashboard、Slice这样的对象,都是先定义模型(superset/models/core.py),才能在视图中访问(superset/views/core.py)。

另一种是不带模型定义的,在Sources::Tables界面上添加的表,都是用的不带模型的接口。按SQLAlchemy的文档,这种接口叫“Core”。

connectors/sqla/models.py文件,大量使用Core的功能,Superset生成SQL语句的函数,就在SqlaTable类里面。


要生成带join的语句(函数名:get_query_str_with_join),先要明确需要传递哪些参数:

kpi_dict:业务要查询的kpi列表。

on_list:关联条件列表。

table_list:从属表。这个概念要稍加解释,多表关联,是以一个表为主,串联起多张表,所以从概念上,可以分为主表和从属表。get_query_str_with_join函数要通过主表的对象来调用,所以只需要传递从属表。

kpi_dict:每个元素是一个list。key:table.id,value:kpi_list。

on_list:每个元素是一个Dict。key:主表id_从属表id,value:关联条件。

说明:虽然SqlaTable定义中不包括id字段,从表结构能看到是有id的:

v2-88feb9d8b8c0c960678d1c23290e60e5_b.jpg

流程:

  • 先处理select_exprs。

依次处理main_table

assist_tables

因为不同表可能存在同名的字段,需要在outer里面加入表名。

  • 生成qry主体:
        qry = sa.select(select_exprs)
        qry = qry.limit(row_limit)
        tbl = self.get_sqla_table()
        qry = qry.select_from(tbl)

遍历辅助表,增加join

                    left_column = on['left_table_name'] + '.' + on['left_code']
                    left_tmp = literal_column(left_column)
                    left_sqla_col = self.make_sqla_column_compatible(left_tmp)
                    right_column = on['right_table_name'] + '.' + on['right_code']
                    right_tmp = literal_column(right_column)
                    right_sqla_col = self.make_sqla_column_compatible(right_tmp)
                    on_clause.append(left_sqla_col == right_sqla_col)
                tbl = tbl.join(table.name, and_(*on_clause))

大概就是这样了。

2019-11-07更新:

tbl.join接受的参数,必须是sqlalchemy.sql.table、或者sqlalchemy.sql.table.alias(),所以上述代码中的tbl.join(table.name, and_(*on_clause)),需要修改。

先根据表名创建一个sqlalchemy.sql.table对象,再用该对象作为join函数的参数。

另,上述代码中的qry = qry.select_from(tbl),需要调整到tbl.join之后。

2019-11-08更新:

三表关联的sql:

2019-11-08 03:50:45,514:DEBUG:root:SELECT count_time AS count_time_19480, count_number AS count_number_19479, production.name AS name_19487, production.brand AS brand_19486, store.name AS name_19495

FROM main.count_record JOIN production ON count_record.production = production.id JOIN store ON count_record.store = store.id

LIMIT 300000 OFFSET 0

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值