数据库:Hive转Presto(一)

本人因为工作原因,经常使用hive以及presto,一般是编写hive完成工作,服务器原因,presto会跑的更快一些,所以工作的时候会使用presto验证结果,所以就要频繁hive转presto,为了方便,我用Python编写了一个转换代码的小程序,工作繁忙,我一点点更新吧。

一、厘清需求

首先,思考具体的需求:

  1. 识别加减乘除等基本运算,presto对于字段属性有严格要求,所以为了一劳永逸,将涉及到计算的字段全部cast为double,但是要注意字符串中出现运算符的,这是不能改的。
  2. 识别<,>,<>,!=,=,<=,>=这些判断符一般用在条件语句,where,join中。以a=b为例(1)a是字段,b是一个字符串,那么a就要cast为varchar,并且b不需要任何cast(2)如果b是数值,那么a要cast为double,并且b不需要任何cas(3)如果b和时间有关,那么a就要case为date(4)如果两边都是字段,那就都cast为varchar。
  3. 常用的一些函数,比如substr,datediff,concat,sum等等,都要转换成对应的presto函数用法。
  4. 使用tkinter创造一个简单的交互界面,方便实时的输入输出,如果有错误就简单的反应错误。

二、代码思路

先处理加减乘除运算,判断符,然后再处理函数,然后添加ui交互界面,最后将代码简单包装为类,条件允许就包装为应用程序,但是公司电脑权限高,所以不太可行。

三、Python代码

python 复制代码
import re
import os
from tkinter import *


class Hive2Presto:
    def __int__(self):
        self.t_funcs = ['substr', 'nvl', 'substring', 'unix_timestamp'] + \
                       ['to_date', 'concat', 'sum', 'avg', 'abs', 'year', 'month', 'ceiling', 'floor']
        self.time_funcs = ['date_add', 'datediff', 'add_months']
        self.funcs = self.t_funcs + self.time_funcs
        self.current_path = os.path.abspath(__file__)
        self.dir = os.path.dirname(self.current_path)
        self.result = []
        self.error = []
        self.filename = ''

    def main(self):
        self.root = Tk()
        self.root.config(bg='#ff741d')  # 背景颜色设置为公司主题色^_^
        self.root.title('Hive转Presto')
        self.win_width = 550
        self.win_height = 500
        self.screen_width = self.root.winfo_screenwidth()
        self.screen_height = self.root.winfo_screenheight()
        self.x = (self.screen_width - self.win_width) // 2
        self.y = (self.screen_height - self.win_height) // 2
        self.root.geometry(f'{self.win_width}x{self.win_height}+{self.x}+{self.y}')

        font = ('楷体', 11)

        self.button = Button(self.root, text='转换', command=self.trans, bg='#ffcc8c', font=font, anchor='e')
        self.button.grid(row=0, column=0, padx=100, pady=10, sticky=W)

        self.file_button = Button(self.root, text='选择文件', command=self.choose_file, bg='#ffcc8c', font=font,
                                  anchor='e')
        self.file_button.grid(row=0, column=1, padx=0, pady=10, sticky=W)

        self.entry = Entry(self.root, width=65, font=font)
        self.entry.insert(0, '输入Hive代码')
        self.entry.grid(row=1, column=0, padx=10, pady=10, columnspan=2)
        self.entry.bind('<Button-1>', self.delete_text)

        self.text = Text(self.root, width=75, height=20)
        self.text.grid(row=2, column=0, padx=10, pady=10, columnspan=2)

        self.des_label = Label(self.root, text='可以复制结果,也有生成的文件,与选取的文件同文件夹', bg='#ffcc8c',
                               font=('楷体', 10))
        self.des_label.grid(row=3, column=0, padx=10, pady=10, columnspan=2)

        s = ''
        for i in range(0, (n := len(self.funcs)), 4):
            if i + 4 <= n:
                s += ','.join(self.funcs[i:i + 4]) + '\n'
            else:
                s += ','.join(self.funcs[i:]) + '\n'
        s = s[:-1]
        self.des_label1 = Label(self.root, text=s, bg='#ffcc8c',
                                font=('楷体', 10))
        self.des_label1.grid(row=4, column=0, padx=10, pady=10, columnspan=2)

        self.root.columnconfigure(0, minsize=10)
        self.root.columnconfigure(1, minsize=10)
        self.root.columnconfigure(0, pad=5)

        self.root.mainloop()

    def replace_func(self, s, res):
        pass

    def func_trans(self, f, f1, func_name, ss, s):
        pass

    def choose_file(self):
        """
        如果代码太多,从text中输入会很卡,直接选择代码文件输入会很快
        :return:
        """
        pass

    def findvar(self, ss):
        """
        搜索与计算有关的字段
        :param ss:
        :return:
        """
        pass

    def mysplit(self, s):
        """
        分割字段
        :param s:
        :return:
        """
        pass

    def extact_func(self, s, func_name):
        pass

    def delete_text(self, event):
        pass

    def trans(self):
        pass


if __name__ == '__main__':
    pro = Hive2Presto()
    pro.__int__()
    pro.main()

先把大致框架写出来,其实我已经完成了,但是代码都在公司电脑,传不出来,需要我重新再打一遍,顺便看看能不能再优化优化。UI界面大致如下:

相关推荐
哈哈幸运13 分钟前
MySQL运维三部曲初级篇:从零开始打造稳定高效的数据库环境
linux·运维·数据库·mysql·性能优化
愚公搬代码34 分钟前
【愚公系列】《Python网络爬虫从入门到精通》055-Scrapy_Redis分布式爬虫(安装Redis数据库)
数据库·爬虫·python
pwzs1 小时前
深入浅出 MVCC:MySQL 并发背后的多版本世界
数据库·后端·mysql
大熊猫今天吃什么1 小时前
【一天一坑】空数组,使用 allMatch 默认返回true
前端·数据库
双叶8361 小时前
(51单片机)LCD显示数据存储(DS1302时钟模块教学)(LCD1602教程)(独立按键教程)(延时函数教程)(I2C总线认识)(AT24C02认识)
c语言·数据库·单片机·嵌入式硬件·mongodb·51单片机·nosql
XY.散人1 小时前
初识Redis · C++客户端list和hash
数据库·redis·缓存
码上飞扬2 小时前
深入 MySQL 高级查询:JOIN、子查询与窗口函数的实用指南
数据库·mysql
海洋与大气科学3 小时前
【matlab】地图上的小图
开发语言·数据库·matlab
Geek__19923 小时前
Sqlite3交叉编译全过程
jvm·数据库·sqlite
·云扬·3 小时前
【技术派后端篇】 Redis 实现用户活跃度排行榜
数据库·redis·缓存