返回顶部
首页 > 资讯 > 后端开发 > Python >基于Python-sqlparse的SQL表血缘追踪解析实现
  • 176
分享到

基于Python-sqlparse的SQL表血缘追踪解析实现

python大数据数据库数据分析hive 2023-09-08 20:09:59 176人浏览 独家记忆

Python 官方文档:入门教程 => 点击学习

摘要

目录 前言 一、主线任务 1.数据治理 2.血缘追踪 3.SQL表血缘 二、实现过程 1.目标效果 2.代码实现 1.功能函数识别 2.SQL标准格式  3.解析AST树 4.最终效果: 点关注,防走丢,如有纰漏之处,请留言指教,非常感谢

目录

前言

一、主线任务

1.数据治理

2.血缘追踪

3.SQL表血缘

二、实现过程

1.目标效果

2.代码实现

1.功能函数识别

2.SQL标准格式

 3.解析AST树

4.最终效果:

点关注,防走丢,如有纰漏之处,请留言指教,非常感谢


前言

之前我在两篇sqlparse的开源库解析中就说过自己在寻找在python编程内可行的SQL血缘解析,JAVA去解析Hive源码实践的话我还是打算放到后期来做,先把Python能够实现的先实现完。主要是HiveSQL的底层就是JAVA代码,怎么改写还是绕不开JAVA的。不过上篇系列我有提到过sqlparse,其实这个库用来解析血缘的话也不是不可以,但是能够实现的功能是有限的,目前我实验还行,一些较为复杂的SQL也能解析得出,算是成功达到可部署服务的水准了,但是根据SQL格式来匹配的话肯定是有些SQL格式不能完全匹配成功的,如果大家有需要血缘分析的SQL可以再次验证一下。

算是填完了之前的部分坑,目前的开发进度已经可以将SQL的表血缘分析追踪实现了,实现字段血缘的功能开发等后续将陆续上线。


一、主线任务

首先来对该项目的目标来分析一下,说到SQL血缘分析,这偏向于数据治理。

1.数据治理

数据治理(Data Governance)是组织中涉及数据使用的一整套管理行为。数据要产生价值,需要一个合理的“业务目标”,数据治理的所有活动应该围绕真实的业务目标而开展,建立数据标准、提升数据质量只是手段,而不是目标。

数据治理的本质是管理数据,因此需要加强元数据管理和主数据管理,从源头治理数据,补齐数据的相关属性和信息,比如:元数据、质量、安全、业务逻辑、血缘等,通过元数据驱动的方式管理数据生产、加工和使用。

数据的质量直接影响着数据的价值,并且直接影响着数据分析的结果以及我们以此做出的决策的质量。数据模型血缘与任务调度的一致性是建管一体化的关键,有助于解决数据管理与数据生产口径不一致的问题,避免出现双重管理不一致的低效管理模式。

2.血缘追踪

数据被业务场景使用时,发现数据错误,数据治理团队需要快速定位数据来源,修复数据错误。那么数据治理团队需要知道业务团队的数据来自于哪个核心库,核心库的数据又来自于哪个数据源头。我们的实践是在元数据和数据资源清单之间建立关联关系,且业务团队使用的数据项由元数据组合配置而来,这样,就建立了数据使用场景与数据源头之间的血缘关系。 数据资源目录:数据资源目录一般应用于数据共享的场景,例如政府部门之间的数据共享,数据资源目录是基于业务场景和行业规范而创建,同时依托于元数据和基础库主题而实现自动化的数据申请和使用。

也就是为什么我们需要解析SQL,追踪建表索引或者引用解析。

3.SQL表血缘

那么其中最重要的就是关于各个数据库之间的数据关系了,关于建表以及插入更新操作都会使数据发生一定的改变,那么这些操作就一定是被允许的?就像原来在网上看到的某某公司程序员删库跑路,或者是一不小心删错数据导致耽误产研线等等。为了防止以上事故的出现必定要为此操作上一层保险,为每个成员设定数据操作权限。这样以来提交的SQL语句就多了一层判断。

二、实现过程

1.目标效果

首先明白一点我们要做出的东西需要呈现一个怎样的形式,其中位于行业前排的无疑是SQLFlow:

 当第一次看到此图我就决定血缘追踪就应该是这个样子,能够清晰的解析出每个字段和表之间的血缘关系。以此我们设定输出的基准,我们要做的项目目标就是如此。

2.代码实现

1.功能函数识别

该功能也是必须要实现的功能,我们需要明白这个SQL主要是干什么事情的。如果是插入INSERT或者是CREATE就有血缘分析的必要,如果是SELECT的话那么做简单的SQL解析即可。有了研究sqlparse源码的成果我们调用相应的函数即可:

sql="select * from table1;insert into table select a,b,c from table2"if __name__ == '__main__':    table_names=[]    #sql=get_sqlstr('read_sql.txt')    stmt_tuple=analysis_statements(sql)    for each_stmt in stmt_tuple:        type_name=get_main_functionsql(each_stmt)        print(type_name)

输出:

 那么对于SELECT我们就SQL涉及到的表追溯即可:

对于CREATE和INSERT的做血缘即可:

2.SQL标准格式

对于传入的SQL我们首先要让这条语句符合标准的SQL语句格式,这样对于传输格式保持一致,兼容很有作用。一般我们都是通过文本来读入。故需要读取文本做处理:

原始文本:

 处理后:

if __name__ == '__main__':    sql=get_sqlstr('read_sql.txt')    print(sql)

 3.解析AST树

得到的SQL无论是ANTRL还是SQLPARSE都是解析为一棵树的形式进行递归回溯。最终都要解析生产的SQL树:

sql="select * from table1;insert into table3 select a,b,c from table2"if __name__ == '__main__':    #sql=get_sqlstr('read_sql.txt')    stmt_tuple=analysis_statements(sql)    for each_stmt in stmt_tuple:        table_names=[]        type_name=get_main_functionsql(each_stmt)        get_ASTTree(each_stmt)

 

4.最终效果:

SQL:

selectb.product_name "产品",count(a.order_id) "订单量",b.selling_price_max "销售价",b.gross_profit_rate_max/100 "毛利率",case when b.business_type =1 then '自营消化' when b.business_type =2 then '服务商消化'  end "消化模式"from(select 'CRM签单' label,date(d.update_ymd) close_ymd,c.product_name,c.product_id,    a.order_id,cast(a.recipient_amount as double) amt,d.cost    from mysql4.dataview_fenxiao.fx_order a    left join mysql4.dataview_fenxiao.fx_order_task b on a.order_id = b.order_id    left join mysql7.dataview_trade.ddc_product_info c on cast(c.product_id as varchar) = a.product_ids and c.snapshot_version = 'SELLING'    inner join (select t1.par_order_id,max(t1.update_ymd) update_ymd,                sum(case when t4.product2_type = 1 and t5.shop_id is not null then t5.price else t1.order_hosted_price end) cost               from hive.bdc_dwd.dw_mk_order t1               left join hive.bdc_dwd.dw_mk_order_status t2 on t1.order_id = t2.order_id and t2.acct_day = substring(cast(DATE_ADD('day',-1,CURRENT_DATE) as varchar),9,2)               left join mysql7.dataview_trade.mk_order_merchant t3 on t1.order_id = t3.order_id               left join mysql7.dataview_trade.ddc_product_info t4 on t4.product_id = t3.MERCHANT_ID and t4.snapshot_version = 'SELLING'               left join mysql4.dataview_scrm.sc_tprc_product_info t5 on t5.product_id = t4.product_id and t5.shop_id = t1.seller_id               where t1.acct_day = substring(cast(DATE_ADD('day',-1,CURRENT_DATE) as varchar),9,2)               and t2.valid_state in (100,200) ------有效订单               and t1.order_mode = 10    --------产品消耗订单               and t2.complete_state = 1  -----订单已经完成               group by t1.par_order_id    ) d on d.par_order_id  = b.task_order_id    where c.product_type = 0 and date(from_unixtime(a.last_recipient_time)) > date('2016-01-01') and a.payee_type <> 1 -----------已收款    UNION ALL    select '企业管家消耗' label,date(c.update_ymd) close_ymd,b.product_name,b.product_id,    a.task_id,(case when a.yb_price = 0 and b.product2_type = 1 then b.selling_price_min else a.yb_price end) amt,    (case when a.yb_price = 0 and b.product2_type = 2 then 0 when b.product2_type = 1 and e.shop_id is not null then e.price else c.order_hosted_price end) cost    from Mysql8.dataview_tprc.tprc_task a    left join mysql7.dataview_trade.ddc_product_info b on a.product_id = b.product_id and b.snapshot_version = 'SELLING'    inner join hive.bdc_dwd.dw_mk_order c on a.order_id = c.order_id and c.acct_day = substring(cast(DATE_ADD('day',-1,CURRENT_DATE) as varchar),9,2)    left join hive.bdc_dwd.dw_mk_order_status d on d.order_id = c.order_id and d.acct_day = substring(cast(DATE_ADD('day',-1,CURRENT_DATE) as varchar),9,2)    left join mysql4.dataview_scrm.sc_tprc_product_info e on e.product_id = b.product_id and e.shop_id = c.seller_id    where  d.valid_state in (100,200) and d.complete_state = 1  and c.order_mode = 10    union ALL    select '交易管理系统' label,date(t6.close_ymd) close_ymd,t4.product_name,t4.product_id,    t1.order_id,(t1.order_hosted_price-t1.order_refund_price) amt,    (case when t1.order_mode <> 11 then t7.user_amount when t1.order_mode = 11 and t4.product2_type = 1 and t5.shop_id is not null then t5.price else t8.cost end) cost    from hive.bdc_dwd.dw_mk_order t1    left join hive.bdc_dwd.dw_mk_order_business t2 on t1.order_id = t2.order_id and t2.acct_day=substring(cast(DATE_ADD('day',-1,CURRENT_DATE) as varchar),9,2)    left join mysql7.dataview_trade.mk_order_merchant t3 on t1.order_id = t3.order_id    left join mysql7.dataview_trade.ddc_product_info t4 on t4.product_id = t3.MERCHANT_ID and t4.snapshot_version = 'SELLING'    left join mysql4.dataview_scrm.sc_tprc_product_info t5 on t5.product_id = t4.product_id and t5.shop_id = t1.seller_id    left join hive.bdc_dwd.dw_fact_task_ss_daily t6 on t6.task_id = t2.task_id and t6.acct_time=date_fORMat(date_add('day',-1,current_date),'%Y-%m-%d')    left join (select a.task_id,sum(a.user_amount) user_amount               from hive.bdc_dwd.dw_fn_deal_asyn_order a               where a.is_new=1 and a.service='Trade_Payment' and a.state=1 and a.acct_day=substring(cast(DATE_ADD('day',-1,CURRENT_DATE) as varchar),9,2)               group by a.task_id)t7 on t7.task_id = t2.task_id              left join (select t1.par_order_id,sum(t1.order_hosted_price - t1.order_refund_price) cost               from hive.bdc_dwd.dw_mk_order t1               where t1.acct_day = substring(cast(DATE_ADD('day',-1,CURRENT_DATE) as varchar),9,2) and t1.order_type = 1 and t1.order_stype = 4 and t1.order_mode = 12               group by t1.par_order_id) t8 on t1.order_id = t8.par_order_id    where t1.acct_day = substring(cast(DATE_ADD('day',-1,CURRENT_DATE) as varchar),9,2)    and t1.order_type = 1 and t1.order_stype in (4,5) and t1.order_mode <> 12 and t4.product_id is not null and t1.order_hosted_price > 0 and t6.is_deal = 1 and t6.close_ymd >= '2018-12-31')aleft join mysql7.dataview_trade.ddc_product_info b on a.product_id = b.product_id and b.snapshot_version = 'SELLING'where b.product2_type = 1 -------标品and close_ymd between DATE_ADD('day',-7,CURRENT_DATE)  and DATE_ADD('day',-1,CURRENT_DATE)GROUP BY b.product_name,b.selling_price_max,b.gross_profit_rate_max/100,b.actrul_supply_num,case when b.business_type =1 then '自营消化' when b.business_type =2 then '服务商消化'  endorder by count(a.order_id) desclimit 10
if __name__ == '__main__':    table_names=[]    sql=get_sqlstr('read_sql.txt')        stmt_tuple=analysis_statements(sql)    for each_stmt in stmt_tuple:        type_name=get_main_functionsql(each_stmt)        blood_table(each_stmt)        Tree_visus(table_names,type_name)        

点关注,防走丢,如有纰漏之处,请留言指教,非常感谢

以上就是本期全部内容。我是fanstuck ,有问题大家随时留言讨论 ,我们下期见

来源地址:https://blog.csdn.net/master_hunter/article/details/127387722

--结束END--

本文标题: 基于Python-sqlparse的SQL表血缘追踪解析实现

本文链接: https://lsjlt.com/news/400616.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • 基于Python-sqlparse的SQL表血缘追踪解析实现
    目录 前言 一、主线任务 1.数据治理 2.血缘追踪 3.SQL表血缘 二、实现过程 1.目标效果 2.代码实现 1.功能函数识别 2.SQL标准格式  3.解析AST树 4.最终效果: 点关注,防走丢,如有纰漏之处,请留言指教,非常感谢 ...
    99+
    2023-09-08
    python 大数据 数据库 数据分析 hive
  • 基于Python-sqlparse的SQL字段血缘追踪解析实现
    目录 前言 一、字段血缘 1.区别字段 2.区别标识符序列 3.功能函数设定 二、字段血缘可视化 点关注,防走丢,如有纰漏之处,请留言指教,非常感谢 前言 SQL解析和血缘追踪的研究现在差不多可以告一段落了,从8月22日写HiveSQ...
    99+
    2023-09-04
    1024程序员节 数据库 mysql python sql
  • Pythonsqlparse解析SQL表血缘追踪实现
    目录引言一、主线任务1.数据治理2.血缘追踪3.SQL表血缘二、实现过程1.目标效果2.代码实现1.功能函数识别2.SQL标准格式3.解析AST树4.最终效果:引言 SQLparse...
    99+
    2024-04-02
  • python目标检测基于opencv实现目标追踪示例
    目录主要代码信息封装类更新utilspython-opencv3.0新增了一些比较有用的追踪器算法,这里根据官网示例写了一个追踪器类 程序只能运行在安装有opencv3.0以上版本和...
    99+
    2024-04-02
  • Python实现Tracert追踪TTL值的方法详解
    Tracert 命令跟踪路由原理是IP路由每经过一个路由节点TTL值会减一,假设TTL值=0时数据包还没有到达目标主机,那么该路由则会回复给目标主机一个数据包不可达,由此我们就可以获...
    99+
    2024-04-02
  • Python实现简单的"导弹" 自动追踪原理解析
    自动追踪算法,在我们设计2D射击类游戏时经常会用到,这个听起来很高大上的东西,其实也并不是军事学的专利,在数学上解决的话需要去解微分方程, 这个没有点数学基础是很难算出来的。但是我们...
    99+
    2024-04-02
  • 基于Android XML解析与保存的实现
    解析XML文件:在Android平台上可以使用SAX、DOM和Android附带的pull解析器解析XML文件;pull解析器提供了各种事件,使用parser.next()方法...
    99+
    2022-06-06
    XML xml解析 Android
  • Java基于ShardingSphere实现分库分表的实例详解
    目录一、简介二、项目使用1、引入依赖2、数据库3、实体类4、mapper5、yml配置6、测试类7、数据一、简介   Apache ShardingSphere ...
    99+
    2024-04-02
  • 基于Android开发支持表情的实现详解
    最近项目需要支持表情,表情的添加和解析实现基本上是参照Android自身的SmileyParser,具体就不多讲了,直接贴上代码: 代码如下:public class Smil...
    99+
    2022-06-06
    android开发 Android
  • 解析thinkPHP基于反射实现钩子的示例分析
    这篇文章将为大家详细讲解有关解析thinkPHP基于反射实现钩子的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。ThinkPHP框架的控制器模块是如何实现 前控制器、后控制器,及如何执行带参数的方...
    99+
    2023-06-15
  • 基于Java实现XML文件的解析与更新
    目录选择一个格式XML 基础创建一个示例配置文件使用 Java 解析 XML使用 Java 访问 XML 的值使用 Java 更新 XML如何保证配置不出问题在你使用 Java 编写...
    99+
    2024-04-02
  • 基于Python实现股票数据分析的可视化
    目录一、简介二、代码1、主文件2、数据库使用文件3、ui设计模块4、数据处理模块三、数据样例的展示四、效果展示一、简介 我们知道在购买股票的时候,可以使用历史数据来对当前的股票的走势...
    99+
    2024-04-02
  • 基于Python实现简单的定时器详解
    所谓定时器,是指间隔特定时间执行特定任务的机制。几乎所有的编程语言,都有定时器的实现。比如,Java有util.Timer和util.TimerTask,JavaScript有set...
    99+
    2024-04-02
  • OSS.Core基于Dapper封装(表达式解析+Emit)仓储层的构思及实现
        最近趁着不忙,在构思一个搭建一个开源的完整项目,至于原因以及整个项目框架后边文章我再说明。既然要起一个完整的项目,那么数据仓储访问就必不可少,这篇文章我主要介绍这个新项目(OSS...
    99+
    2024-04-02
  • 基于Python实现文件的压缩与解压缩
    目录zip文件tar.gz文件rar文件7z文件在日常工作中,除了会涉及到使用Python处理文本文件,有时候还会涉及对压缩文件的处理。 通常会涉及到的压缩文件格式有: rar:W...
    99+
    2024-04-02
  • 基于Python实现帕累托图的示例详解
    目录1.定义2.帕累托原理3.帕累托原则如何应用于商业4.什么时候应该使用帕累托图5.帕累托图与条形图有何不同6.帕累托图的替代方案7.帕累托图的好处7.1 专注解决问题7.2 提供...
    99+
    2023-03-11
    Python实现绘制帕累托图 Python绘制帕累托图 Python帕累托图
  • 基于Python实现配置热加载的方法详解
    目录背景如何实现使用多进程实现配置热加载使用signal信号量来实现热加载采用multiprocessing.Event 来实现配置热加载结语背景 由于最近工作需求,需要在...
    99+
    2024-04-02
  • 基于Python实现的恋爱对话小程序详解
    目录导语一、小简介二、代码演示1)导入模块2)倒计时3)画2份不同的礼物4)二种选择是不同的绘图倒计时之后就是绘制你回答的那个礼物。5)弹窗设计的文字(可修改)三、效果展示1)视频展...
    99+
    2024-04-02
  • 基于Docker与Jenkins实现自动化部署的原理解析
    原理:Jenkins构建(开发提交代码到代码管理平台),Jenkins处理(Jenkins获取远程代码,自动将源代码实现打包,执行shell脚本启动)。 Linux安装Docke...
    99+
    2024-04-02
  • 基于python实现垂直爬虫系统的方法详解
    html_downloader from urllib import request def download(url): if url is None: r...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作