Python搞定爬取表映射文档翻译成执行语句(DB2)

作者企鹅:595696297
技术交流群:127591054

工作中用到所以开发了一个,。
映射文档如下格式。格式按照自己需求参考。我这里有N列,可以参考。做必要改动即可。
Python搞定爬取表映射文档翻译成执行语句(DB2)
Python搞定爬取表映射文档翻译成执行语句(DB2)

下面是运行结果
Python搞定爬取表映射文档翻译成执行语句(DB2)

其他SQL语句都是基本差不多的,看一下代码,略微改动一下,就可以完美移植各种数据库的映射语句。

简单说一下怎么使用
下面是目录的结构,文档的格式在ExcelFile文件夹中。

Python搞定爬取表映射文档翻译成执行语句(DB2)

1、首先要保证安装Python3.x版本。我这里用的是3.0
2、安装所需要包,用win+R进入CMD窗口输入:python -m pip install xlrd
3、按照标准化文档的格式写映射文档,然后放到ExcelFile目录下,名字格式:数据标准化拆分-XXXXX
4、按照自己需求配置,配置文件。同级目录:Config.txt

import xlrd
#import pandas as pd
import collections
import random
import time
from datetime import date,datetime
import sys,os,io


#Author JackChiang
#遇到问题:联系QQ595696297哦!

#配置名称置为空等待读取
userspace = ''
sheetname = ''
if_add_flog = ''
if_auto_load = ''
if_auto_mkdir = ''

#获取当前脚本所在路径
def cur_file_dir(): 
    path = sys.path[0] #获取脚本路径
    if os.path.isdir(path):#判断脚本是文件还是编译后的文件,如果是脚本返回脚本目录,如果是编译文件,返回编译文件路径
        return path
    elif os.path.isfile(path):
        return os.path.dirname(path)
#读取配置文件
def read_config(fileone):
                #申明修改全局变量
        global userspace,sheetname,if_add_flog,if_auto_load,if_auto_mkdir   
        f1 = open(fileone,'r+')
        while 1:
            lines = f1.readlines(10)
            if not lines:
                break
            for line in lines:
                line=line.strip('\n')
                file_key = line.split('=')[0]
                file_value = line.split('=')[1]
                if file_key == 'USERSPACE':
                    userspace = file_value              
                if file_key == 'SHEETNAME':
                    sheetname = file_value              
                if file_key == 'IF_ADD_FLOG':
                    if_add_flog = file_value
                if file_key == 'IF_AUTO_LOAD':
                    if_auto_load = file_value
                if file_key == 'IF_AUTO_MKDIR':
                    if_auto_mkdir = file_value    
        if userspace != '' and sheetname != '' and if_add_flog != '' and if_auto_load != '' and if_auto_mkdir != '':
            logMsg.write('配置文件读取完成!\n')
            return True
        else:
            logMsg.write('配置文件读取失败!\n')
            return False

#搜索当前标准化文档的文件
def file_name(file_dir):
    L = []
    #TRUE代表开启自动搜索全部文档,否则代表读取file文件目录
    if if_auto_load != 'TRUE':
        f2 = open(file_dir+"\\file.txt",'r+')
        while 1:
            lines = f2.readlines(100)
            if not lines:
                break
            for line in lines:
                line=line.strip('\n')
                L.append(line)
        f2.close()
        print('从文件读取目录文件完成!')
        logMsg.write('从文件读取目录文件完成!\n')
    else:
        f1 = open(file_dir+"\\file.txt",'w')
        ExcelFile = file_dir+'\\ExcelFile'
        #清空文件内容
        f1.truncate()
        for root, dirs, files in os.walk(ExcelFile):  
            for file in files:
                filename = os.path.splitext(file)[0]
                filespl  = os.path.splitext(file)[1]
                if '数据标准化拆分' in filename:
                    if filespl == '.xls':
                       path = '%s%s%s' % (root, '\\', file)
                       L.append(path)
                       f1.write(path)
                       f1.write('\n')
                       logMsg.write(file + '文件写入!!\n')
        print('写入目录文件完成!')
        logMsg.write('写入目录文件完成!\n')
        f1.close()
    

    
    return tuple(L)

#读取Excel文件中的内容,找到没张表的位置   
def read_excel_one(sheet):
    #开始一行一行遍历锁定ALL位置
    flog = 0
    flog_count = 0
    L = []
    j = 0
    L1 = []
    #dict = {}
    #使用有序字典
    dict = collections.OrderedDict()
    for i in range(sheet.nrows):
        value = sheet.cell_value(i, 3)
        table_name = sheet.cell_value(i, 1)
        mode_value = sheet.cell_value(i, 0)
        if value == 'ALL':
            j = i
            if j != 1:
                L.append(j)
                
            L.append(i)
            L.append(table_name)
            L.append(mode_value)
            flog_count = flog_count + 1
            #print('%s 找到啦!第%s次有ALL:%s'%(flog_count,i,table_name))
    L.append(sheet.nrows-1)
    #print(L)
    #找到第一次出现ALL的位置代表表的开始,第二次出现的前一个位置代表结束。
    #遍历列表
    print(len(L))
    for i in range(len(L)):
        #print(i+1,L[i])
        if(i+1)%4==0:
            if i+1 != len(L):
                #print(L[i-3])
                #print(L[i-2])
                #print(L[i-1])
                #print(L[i])
                L1.append(L[i-1])
                L1.append(L[i-3])
                L1.append(L[i]-1)
                dict[L[i-2]] = L1
                L1 = []
            else:     
            #处理最后一个情况
                L1.append(L[i-1])
                L1.append(L[i-3])
                L1.append(L[i])
                dict[L[i-2]] = L1
                L1 = []
    #print(dict)
    return dict 

#创建目录
def mkdir_one(fileone,cell_value):
    path_one = fileone + '\\' + cell_value
    # 判断路径是否存在
    # 存在     True
    # 不存在   False
    isExists=os.path.exists(path_one)
    # 判断结果
    if not isExists:
        # 如果不存在则创建目录
        # 创建目录操作函数
        os.makedirs(path_one) 
 
        logMsg.write(path_one +' 创建成功\n')
    else:
        # 如果目录存在则不创建,并提示目录已存在
        logMsg.write(path_one +' 目录已存在\n')
    return path_one

#翻译语句
def read_table_one(dict,sheet,fileone):
    ddlFile = fileone + '\\DDL'
    defFile = fileone + '\\DDL\\DEFAULT_DDL'
    #cell_value = sheet.cell_value(2,0)
    #path_one = mkdir_one(ddlFile,cell_value)
    #判断是否需要创建文件夹,还是使用默认
    path_one = defFile
        
    #遍历字典取值
    for k,v in dict.items():
        cell_value = v[0] #BANK : ['IMBS',1, 18]
        if if_auto_mkdir == 'TRUE':
            path_one = mkdir_one(ddlFile,cell_value)
            
        logMsg.write('%s 表的行范围为: %s\n'%(k,v))
        f1 = open('%s\\%s_%s.ddl'%(path_one,cell_value,k),'w',encoding='utf-8')
        page = '--------------------------------------------------\n'
        f1.write(page)
        f1.write('-- Create Table '+ cell_value + '.'+ k+'\n')
        f1.write(page)
        f1.write('Create Table '+ cell_value + '.'+ k+'(\n')
        row_pri_name = ''
        row_table_decs = ''
        Str_com = []
        for i in range(v[1]+1,v[2]+1):
            row_data = sheet.row_values(i)
            if row_data[5] == 'INTEGER':
                table_cloumn_type = row_data[5]
            elif row_data[5] == 'TIMESTAMP':
                table_cloumn_type = row_data[5]
            elif row_data[5] == 'DATE':
                table_cloumn_type = row_data[5]
            elif row_data[5] == 'BIGINT':
                table_cloumn_type = row_data[5]
            elif row_data[5] == 'DECIMAL':
                row_data7 = row_data[7]

                if row_data[6] == '':
                    logMsg.write('在%s表中的%s字段长度没有写!!\n'%(k,row_data[3]))
                    return;
                if row_data[7] == '':
                    logMsg.write('在%s表中的%s字段精度没有写!!默认为0 \n'%(k,row_data[3]))
                    row_data7 = 0
                    
                table_cloumn_type = '%s(%d,%d)'%(row_data[5],row_data[6],row_data7)
            else:
                table_cloumn_type = '%s(%d)'%(row_data[5],row_data[6])

            if row_data[10] == 'Physical Primary Key':
                table_pri = '             NOT NULL    ,'
                if row_pri_name == '':
                        row_pri_name = row_data[3]+','
                else:
                        row_pri_name = row_pri_name+row_data[3]+','  
            else:
                table_pri = '                         ,'

            #读到最后一行,去掉逗号
            if i == v[2] and if_add_flog != 'TRUE':
                table_pri = table_pri[:-1]+')'
                
            #拼接字段
            f1.write('    '+row_data[3]+'                       '+table_cloumn_type+table_pri)
            f1.write('\n')

            #注解放入列表
            if row_data[4] != '': 
                Str_com.append('Comment on Column %s.%s.%s               is \'%s\';'%(cell_value,k,row_data[3],row_data[4]))
            row_table_decs = row_data[2]
            #print(row_data)
            
        if if_add_flog == 'TRUE':
            f1.write('    EFF_DT                         DATE                NOT NULL    ,\n')
            f1.write('    END_DT                         DATE                            ,\n')
            f1.write('    JOB_SEQ_ID                     INTEGER                         )\n')
            f1.write('in %s\n'%(userspace))
            f1.write('Partitioning Key ('+row_pri_name+'EFF_DT) Using Hashing\n')
            f1.write('Compress Yes;\n')
        else:
            f1.write('in %s\n'%(userspace))
            f1.write('Partitioning Key ('+row_pri_name[:-1]+') Using Hashing\n')
            f1.write('Compress Yes;\n')

            
        #创建注解
        f1.write('Comment on Table '+cell_value + '.'+ k+'               is \''+ row_table_decs + '\';\n')
        for i in Str_com:
            f1.write(i)
            f1.write('\n')
        f1.write('\n')

        if if_add_flog == 'TRUE':
            #创建索引
            f1.write(page)
            f1.write('-- Create Index '+cell_value + '.'+ k+'_'+time.strftime("%Y%m%d")+'_1\n')
            f1.write(page)
            f1.write('Create Index '+cell_value + '.'+ k+'_'+time.strftime("%Y%m%d")+'_1\n')
            f1.write('  on '+cell_value + '.'+ k+'\n')
            f1.write('  (END_DT)    Allow Reverse Scans;\n')
            f1.write('\n')
            f1.write(page)
            f1.write('-- Create Index '+cell_value + '.'+ k+'_'+time.strftime("%Y%m%d")+'_2\n')
            f1.write(page)
            f1.write('Create Index '+cell_value + '.'+ k+'_'+time.strftime("%Y%m%d")+'_2\n')
            f1.write('  on '+cell_value + '.'+ k)
            f1.write('  (JOB_SEQ_ID)    Allow Reverse Scans;\n')
            f1.write('\n')

        #创建主键    
        f1.write(page)
        SQLKey = random.randint(100000000000000,999999999999999)
        f1.write('-- Create Primary Key SQL%d\n'%SQLKey)
        f1.write(page)
        f1.write('alter table '+cell_value + '.'+ k+'\n')
        f1.write('  add constraint SQL%d\n'%SQLKey)
        if if_add_flog == 'TRUE':
            f1.write('Primary Key ('+row_pri_name+' EFF_DT);\n')
        else:
            f1.write('Primary Key ('+row_pri_name[:-1]+');\n')
        f1.close()   
def execute_mode(L_name):
    #循环处理文档
    for L in L_name:   
        ExcelFile=xlrd.open_workbook(L)
        path_name = L.split('\\')[-1]
        SheelList = sheetname.split(',')
        #获取目标EXCEL文件sheet名
        L_Sheetname = []
        Sheetname_one = ExcelFile.sheet_names()
        for  Sheet_NM in Sheetname_one:
                for Shee_t in SheelList:
                    if Sheet_NM == Shee_t:
                        L_Sheetname.append(Sheet_NM)
                    else:
                        pass

                #print(L_Sheetname)
                
                for Sheet_NM in L_Sheetname:
                    sheet=ExcelFile.sheet_by_name(Sheet_NM)
                    print('文件名:%s Sheet名字:%s Sheet行数:%s Sheet列数:%s'%(path_name,sheet.name,sheet.nrows,sheet.ncols))
                    logMsg.write('文件名:%s Sheet名字:%s Sheet列数:%s Sheet行数:%s\n'%(path_name,sheet.name,sheet.nrows,sheet.ncols))
                    #rows=sheet.row_values(2)#第三行内容
                    #cols=sheet.col_values(1)#第二列内容
                    #value = sheet.cell_value(1, 3)
                    #print(value)    
                    dict = read_excel_one(sheet)
                
                    read_table_one(dict,sheet,fileone)
                L_Sheetname = []
                    
        print('文件:%s 处理完成!!!'%path_name)
        logMsg.write('文件:%s 处理完成!!!\n'%path_name)
        print('===========================================\n')
        logMsg.write('===========================================\n')
        print('===========================================\n')
        logMsg.write('===========================================\n')
    
        
#用pandas 实现(暂时放弃)
#def read_excel_two(filepath):
#    df = pd.read_excel(filepath)
#    print(df.shape)
#    print(df.dtypes)
#    #print(df[df.字段代码 == 'ALL'])


###################################################
    ###################开始##################
#记录日志
fileone = cur_file_dir()


logMsg = open(fileone+"\\RunLog.txt",'w',encoding='utf-8')
con_flog = read_config(fileone+"\\Config.txt")

v1 = '%s、表空间已经设置为:%s:'%(1,userspace);
v2 = '%s、sheet页名字已经设定为:%s:'%(2,sheetname)
v3 = '%s、是否加ODS末尾字段状态:%s:'%(3,if_add_flog)
v4 = '%s、是否自动读取ExcelFile文件夹文件状态为:%s:'%(4,if_auto_load)
v5 = '%s、是否自动根据模式名创建文件状态为:%s:'%(5,if_auto_mkdir)
print(v1)
print(v2)
print(v3)
print(v4)
print(v5)
logMsg.write(v1+'\n')
logMsg.write(v2+'\n')
logMsg.write(v3+'\n')
logMsg.write(v4+'\n')
logMsg.write(v5+'\n')

#可以从L取数,但这里灵活一点从文件取数
#如果需要自动识别所有,配置文件修改为TRUE,否则手动决定目录
L = file_name(fileone)
#print(L[1])
if con_flog == True:
    execute_mode(L)
    
    print('程序执行完毕!!!')
    logMsg.write('=========程序执行完毕!!!============\n')
    logMsg.close()
else:
    print('配置文件格式错误!!')










上一篇:Python连接DB2操作的一个小例子


下一篇:【阿里云ACE】杭州新春活动,不一样的新年,不一样的程序猿们!