【数仓开发】5-Excel模板生成HiveDDL建表SQL

根据excel模板生成Hive DDL建表SQL

1.excel模板

image-20220802144947790

2.excel_gen_ddl_sql.py

#!/usr/bin/python
# -*- coding: utf-8 -*-

"""
功能: excel数据仓库物理模型生成 ddl_表名.sql文件
输入数据:文件名以「数据模型.xls or 数据模型.xlsx」结尾
输出数据:ddl_表名.sql
"""
import os
import numpy as np
import pandas as pd
from pandas import DataFrame
#正则
import re

# HDFS 数据仓库路径
HDFS_DIR = "'hdfs://host:8020/dw/"

# todo 读Excel生成sql文件
def read_excel_gen_sql(file, stored_as="orc", field_delimited="\\t", collection_delimited="-", map_delimited=":"):
    excel = pd.read_excel(file, None)
    sheet_names = excel.keys()
    for sheet_name in sheet_names:
        #sheet页以ods、dwd、dim、dws、ads开头
        if re.match("^ods.*|^dwd.*|^dim.*|^dws.*|^ads.*",sheet_name):
            df = DataFrame(pd.read_excel(file, sheet_name))
            # 获取表名和表注释
            table_name = df.columns.values[1]
            table_comment = df.iloc[0][1]
            # 准备获取属性字段
            # 删除第一行和第二行无用数据
            df.drop([0, 1], inplace=True)
            # 删除空行
            df.dropna(axis='index', how='all', inplace=True)
            # 取出分区字段行
            partition_row = np.array(df[-1:]).tolist()[0]
            # 获取分区字段名
            partition_field_name = partition_row[0]
            # 获取分区字段类型
            partition_field_type = partition_row[1]

            # 判断是否存在分区字段 "dt"
            if partition_field_name == "dt":
                # 删除分区行,获得所有字段
                field_df = df[:-1]
            else:
                # 获得所有字段
                field_df = df

            # 获取所有列名
            columns = df.columns.values
            # 获取字段名
            field_name = field_df[columns[0]]
            # 获取字段类型
            field_type = field_df[columns[1]]
            # 获取字段注释
            field_comment = field_df[columns[2]]

            sql_template = "create table if not exists " + table_name.lower() + " (\n"
            count = 1
            # 遍历所有字段
            for i in field_name.keys():
                sql_template += "    " + str(field_name[i].lower()) + " " \
                                + str(field_type[i]) + "  comment \'" + str(field_comment[i]) + "\'"
                if count == len(field_name):
                    sql_template += "\n"
                else:
                    sql_template += ",\n"
                count += 1

            # 判断是否存在分区字段"dt"
            # print(partition_field_name)
            if partition_field_name != "dt":
                sql_template = sql_template + ")\n" + "comment '" + table_comment + "' \n" \
                               + "stored as " + stored_as + " \n" \
                               + "location " + HDFS_DIR + table_name[0:3] + "/" + table_name.lower() + "';\n"
            else:
                sql_template = sql_template + ")\n" + "comment '" + table_comment + "' \n" \
                               + "partitioned by(" + partition_field_name + " " + partition_field_type + ") \n" \
                               + "row format delimited '" + field_delimited + "' \n" \
                               + "stored as " + stored_as + " \n" \
                               + "location " + HDFS_DIR + table_name[0:3].lower() + "/" + table_name.lower() + "';\n"

            print(sql_template)

            # 创建 ddl 文件
            file_name = "ddl_" + sheet_name.lower() + ".sql"
            # 创建文件对象,覆盖写方式
            file_object = open(file_name, 'w')
            try:
                # 创建文件
                file_object.write(sql_template)
            finally:
                # 关闭文件对象
                file_object.close()

# todo 遍历目录下【数据模型.xls】、【数据模型.xlsx】 结尾 excel生成sql文件
def read_dir_gen_sql(dir_name):
    file_list = os.listdir(dir_name)
    print(file_list)
    for file in file_list:
        # 处理【数据模型.xls】、【数据模型.xlsx】 结尾的文件
        if file.endswith('数据模型.xls') or file.endswith('数据模型.xlsx'):
            # 生成建表文件
            read_excel_gen_sql(file)

if __name__ == '__main__':
    # 当前目录
    # read_dir_gen_sql('.')

    # 指定文件
    file = "/Users/didi/mine/software/idea/code/python_study/gen_sql_ddl/数据治理_生成域_数据模型.xlsx"
    read_excel_gen_sql(file)


3.使用说明

1.默认读取和py文件同级目录的以 【数据模型.xls】、【数据模型.xlsx】 结尾 文件,eg:也可以改读文件代码逻辑。
2.在字段转换的会报错,转换str异常,看看表格是否都填充完。
2.excel要保存好,在编辑中,会生成一个‘~$dwd_govern_score_task_rawmaterial_数据模型.xlsx’这种文件,会报错。
3.excel可以多个sheet页,命名以 ods、dwd、dws、ads、dim前缀命名。
4.默认会有LOCATION的路径,可选择不用。

报错

    sql_template += "    " + str(field_name[i].lower()) + " " \
AttributeError: 'float' object has no attribute 'lower'

原因:字段、字段类型、字段说明有空值

posted @ 2022-08-02 15:04  来自遥远的水星  阅读(488)  评论(0编辑  收藏  举报