python通过配置文件从excel文件导入数据数据库

本文介绍了使用Python如何通过读取Excel文件中的数据,如药品信息、医保目录等,配置ODBC连接,然后将数据插入到不同类型的数据库表中,如西药中成药、中药饮片等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Python通过读取excel数据处理后导入到数据库表中

配置文件

# 数据库连接
[database]
DRIVER = {ODBC Driver 13 for SQL Server}
SERVER = 192.168.xxx.xx
# DATABASE = db_20230407
DATABASE = db
UID = sa
PWD = aaaaaaa

# excel文件路径
[filepath]
Adr = g:\drb\医保三目录202301111版a.xlsx

# 对应表名
[table]
西药中成药 = hbsyb_xcy_bzk
中药饮片 = hbsyb_zyyp_bzk
中药配方颗粒 = hbsyb_zypfkl_bzk
诊疗项目 = hbsyb_zl_bzk
材料 = hbsyb_cl_bzk
单件 = hbsyb_djcl_bzk

# 表对应的字段名
[西药中成药]
药品代码 = YBDM
注册名称 = ZCMC
商品名称 = SPMC
注册剂型 = zcjx
实际剂型 = sjjx
注册规格 = zcgg
实际规格 = sjgg
包装材质 = bzcz
最小包装数量 = zxbzsl
最小制剂单位 = zxzjdw
最小包装单位 = zxbzdw
药品企业 = ypscqy
上市药品持有人 = ssypcyr
批准文号 = pzwh
药品本位码 = ypbwm
市场状态 = sc_state
医保药品名称 = ybypmc
甲乙丙类标识 = ybbxdj
协议期内谈判药品标识 = tp_xyq_bs
谈判药品协议有效期起始日期 = tp_xyq_ksrq
谈判药品协议有效期截止日期 = tp_xyq_zzrq
限定支付范围药品自费标识 = xdzffwbs
医保支付标准(最小制剂单位) = ybzfbz_zxzjdw
医保支付标准(最小包装单位) = ybzfbz_zxbzdw
数据来源 = sjly
修改字段 = xgzd
谈判药医保支付标准(最小包装单位) = tpyzfbz_zxbzdw
集采药品医保支付标准 = ybzfbz
“两病”用药医保支付标准 = eb_yyzfbz
是否按特药门诊结算(享受“单独支付”待遇) = if_tyzf
是否三定管理 = ifsdgl
变更日志 = bqbgrz
是否试点药品(527) = ifsdyp

[中药饮片]
国家中药饮片代码 = ybdm
中药饮片名称 = zcmc
药材名称 = ycmc
炮制方法 = pzff
功效分类 = gxfl
药材科(族)来源 = ycly
药材种来源 = yczl
药用部位 = yybw
性味与归经 = xwgj
功能与主治 = gnzz
用法与用量 = yfyl
医保支付政策 = ybzfzc
甲乙丙类标识 = ybbxdj
数据来源 = sjly

[单件]
耗材代码 = ybdm
一级分类 = yjfl
二级分类 = ejfl
三级分类 = sjfl
医保通用名 = yb_tym
材质 = cz
特征 = tz
耗材企业 = scqy
注册证号 = zczh

[中药配方颗粒]
中药配方颗粒代码 = ybdm
中药配方颗粒名称 = zcmc
规格 = zcgg
包装规格 = bzgg
中药配方颗粒执行标准 = zypfbz
执行标准(国标/省标) = bzlx
保质期 = bzq
最小计价计量单位 = zxjjdw
不良反应监测信息 = blfyyjcxx
上市备案号 = ssbah
上市备案时间 = ssbasj
上市备案状态 = ssbazt
上市备案省局 = ssbasj1
生产企业 = scqy
生产地址 = scdz
销往省份 = xwsf
中药饮片代码 = zyypdm
中药饮片名称 = zyypmc
中药饮片执行标准 = zyypbz
医保类别 = ybbxdj
数据来源 = sjly
支付政策 = ybzfzc

[诊疗项目]
国家医疗服务项目代码 = ybdm
国家医疗服务项目名称 = ybmc
地方医疗服务项目代码 = df_ybdm
地方医疗服务项目名称 = df_mc
项目内涵 = xmlh
除外内容 = cwnr
计价单位 = jjdw
项目说明 = xmsm
政策标识 = zcbs
备注 = beizhu
一级 = gl_1
二级 = gl_2
三级 = gl_3
部属 = gl_bs
原编码 = y_ybbm
变更日志 = bgrz

[材料]
耗材代码 = ybdm
一级分类 = yjfl
二级分类 = ejfl
三级分类 = sjfl
医保通用名 = yb_tym
材质 = cz
特征 = tz
耗材企业 = scqy
政策标识区 = ybzfzc
注册证号 = zczh
耗材类型 = hclx
数据来源 = sjly
变更日志 = bgrz
属类代码 = sldm
置换材料分类 = zhclfl



运行代码

import xlwings as xs
import os
# import pandas as pd
import pyodbc
from openpyxl import load_workbook
import sys
import re
import configparser

class Main(object):
    def __init__(self):
        # Excel所在路径
        config = configparser.ConfigParser()
        config.read(r'excel_config.ini', encoding="utf-8")
        # config.read('excel_config.ini')
        Adr = config.get(r'filepath', 'Adr')
        tab_jl = config.options('table')
        # print(tab_jl)
        # Adr = r"g:\liujun\drb\医保三目录202301111版a.xlsx"
        # 定义正则表达式
        pattern = r'\d+'
        # 匹配字符串中的数字
        match_ver = re.findall(pattern, Adr)
        # print(match_obj)
        wb = load_workbook(filename=Adr)
        # 获取所有的表名
        sheet_names = wb.sheetnames
        # print(sheet_names)
        # 打印所有的表名
        for sheet_name in sheet_names:
            for tab_value in tab_jl:
                if tab_value in sheet_name and tab_value == '西药中成药':
                    sh = sheet_name  # 待处理的表名
                    Tbn = config.get(r'table', tab_value)
                    Dic = self.Excel_MySQL_Columns(config, tab_value)
                    # print(Dic, 1)
                    self.Excel_Insert_MySQL(Adr, sh, Dic, Tbn, match_ver, config)
                # if tab_value in sheet_name and tab_value == '中药饮片':
                #     sh = sheet_name  # 待处理的表名
                #     Tbn = config.get(r'table', tab_value)
                #     Dic = self.Excel_MySQL_Columns(config, tab_value)
                #     self.Excel_Insert_MySQL(Adr, sh, Dic, Tbn, match_ver, config)
                # if tab_value in sheet_name and tab_value == '中药配方颗粒':
                #     sh = sheet_name  # 待处理的表名
                #     Tbn = config.get(r'table', tab_value)
                #     Dic = self.Excel_MySQL_Columns(config, tab_value)
                #     self.Excel_Insert_MySQL(Adr, sh, Dic, Tbn, match_ver, config)
                # if tab_value in sheet_name and tab_value == '诊疗项目':
                #     sh = sheet_name  # 待处理的表名
                #     Tbn = config.get(r'table', tab_value)
                #     Dic = self.Excel_MySQL_Columns(config, tab_value)
                #     self.Excel_Insert_MySQL(Adr, sh, Dic, Tbn, match_ver, config)
                # if tab_value in sheet_name and tab_value == '材料':
                #     sh = sheet_name  # 待处理的表名
                #     Tbn = config.get(r'table', tab_value)
                #     Dic = self.Excel_MySQL_Columns(config, tab_value)
                #     self.Excel_Insert_MySQL(Adr, sh, Dic, Tbn, match_ver, config)
                # if tab_value in sheet_name and tab_value == '单件':
                #     sh = sheet_name  # 待处理的表名
                #     Tbn = config.get(r'table', tab_value)
                #     # print(Tbn, sh)
                #     Dic = self.Excel_MySQL_Columns(config, tab_value)
                #     # print(Dic, 2)
                #     self.Excel_Insert_MySQL(Adr, sh, Dic, Tbn, match_ver, config)
        wb.close()

    def conn(self, config):
        DRIVER = config.get('database', 'DRIVER')
        SERVER = config.get('database', 'SERVER')
        DATABASE = config.get('database', 'DATABASE')
        UID = config.get('database', 'UID')
        PWD = config.get('database', 'PWD')
        # print(DRIVER, SERVER, DATABASE, UID, PWD)
        conn = pyodbc.connect(
            f'DRIVER={DRIVER}; SERVER={SERVER}; DATABASE={DATABASE}; UID={UID}; PWD={PWD}')
        return conn

    def Excel_Insert_MySQL(self, adr, sh, dic, tbn, match_ver, config):
        app = xs.App(visible=False, add_book=False)
        # print(adr)
        app.screen_updating = False
        app.display_alerts = False
        # 打开工作簿
        wb = app.books.open(adr, read_only=True)
        sh = wb.sheets(sh)
        # 统计sh中行数
        nr = sh.used_range.last_cell.row + 1  # 增加1行以防止最后一行被丢弃处理

        # 统计sh中列数
        nc = sh.used_range.last_cell.column
        # print(nr, nc)
        i = 1
        # 查找Excel与数据库中表对应的列
        while i < nc:
            rv = sh.range((i, 1), (i, nc)).value
            # print(rv)
            # 创建一个空字典,用于存储每列所在的位置
            title_dic = {}
            for k in dic:
                # print(rv)
                if k in rv:
                    # print(k)
                    title_dic.update({dic[k]: rv.index(k)})
            # 如果在Excel中只找到了一列或部分列,则提示,并退出循环
            # print(title_dic)
            if len(title_dic) > 1 and len(title_dic) != len(dic):
                print('请核查列名,是否与Excel中一致。')
                print(title_dic.keys())
                print(dic.values())
                break
                # 退出程序
                sys.exit(1)
                # 关闭工作簿
                wb.close()
                # 关闭Excel应用程序
                app.quit()
            # 判断要查找的列是否都在Excel中找到
            # print(len(title_dic) == len(Dic))
            if len(title_dic) == len(dic):
                # 将标题行所在行数,赋值给sr
                sr = i
                break
            i += 1
        # 增加类别代码及版本号
        dic['lbdm'] = 'LBDM'
        dic['ver'] = 'ver'
        if tbn == 'hbsyb_xcy_bzk':
            Lbdm = 'XCY'
        if tbn == 'hbsyb_cl_bzk':
            Lbdm = 'cl'
        if tbn == 'hbsyb_djcl_bzk':
            Lbdm = 'djcl'
        if tbn == 'hbsyb_zl_bzk':
            Lbdm = 'zl'
        if tbn == 'hbsyb_zypfkl_bzk':
            Lbdm = 'kl'
        if tbn == 'hbsyb_zyyp_bzk':
            Lbdm = 'zyyp'
        # 创建数据库链接
        # print(sr)
        try:
            conn = self.conn(config)
            cur = conn.cursor()
        except Exception as e:
            print(e)
        # 创建追加插入sql语句
        sql = f"insert into {tbn} (" + ','.join(list(dic.values())) + ") values (" + ','.join(['?'] * len(dic)) + ")"
        # 从收入数据开始行读取
        # print(sql)
        i = sr + 1
        # 插入成功行数
        i1 = 0
        # print(nr)
        while i < nr:
            rv = sh.range((i, 1), (i, nc)).value
            Arr = []
            # 建立集合
            list1 = []
            for k in title_dic.values():
                if rv[k] is not None:
                    if len(str(rv[k])) >= 250:
                        value_new = rv[k].replace(" ", "")[:200]
                    else:
                        value_new = rv[k]
                else:
                    value_new = rv[k]
                Arr.append(value_new)
                # 集合添加数据
                list1.append(rv[k])
                # print(list1,  'aa')
                # print(len(list1) == len(title_dic), 1)
                if len(list1) == len(title_dic):  # 判断集合数量是否添加完毕
                    # print(list1[0], i)
                    # i1 += 1
                    # 判断第一个是否为空 为空则赋值
                    if list1[0] is None:
                        # print(list1[0], 2)
                        insert_flag = True
                        list1.clear()
                    else:
                        insert_flag = False
                        list1.clear()
                    # print(insert_flag, 3)
                else:
                    insert_flag = False
                    # list1.clear()
            # 终止循环
            # print(insert_flag, 3)
            # print(insert_flag)
            # 防止空行导入数据
            if insert_flag is True:
                break

            if insert_flag is False:
                # print(i, )
                Arr.append(Lbdm)
                Arr.append("".join(match_ver))  # 将list数据转成字符串
                # Arr = str(Arr)
                # print(sql, Arr)
                # 调用SQL
                try:
                    cur.execute(sql, Arr)
                # print(res.fetchone())
                # cur.executemany(sql, Arr)
                # 执行操作
                    conn.commit()
                    suc_fail = Falsealse
                except Exception as e:
                    suc_fail = True
                    error = e
            if suc_fail is True:
                break
            i += 1
            i1 += 1
        cur.close()
        conn.close()
        if suc_fail:
            print(f'共【{nr - 1}】条,插入【{Lbdm}】数据失败,失败原因:', error)
        else:
            print(f'共【{nr-1}】条,成功插入【{Lbdm}】数据【{i1}】条')
        # 关闭工作簿
        wb.close()
        # 关闭Excel应用程序
        app.quit()

    def Excel_MySQL_Columns(self, config, tab_value):
        # 创建Excel列与MySQL数据库中表列之间的对应关系,Excel中列为键,MySQL中列为值
        # sheet = wb.get_sheet_by_name(sh)
        # column_names = []
        dic = {}
        if tab_value == '单件':
            for values in config.options(tab_value):
                dic[values] = config.get(tab_value, values)
        if tab_value == '西药中成药':
            for values in config.options(tab_value):
                dic[values] = config.get(tab_value, values)
        if tab_value == '中药饮片':
            for values in config.options(tab_value):
                dic[values] = config.get(tab_value, values)
        if tab_value == '中药配方颗粒':
            for values in config.options(tab_value):
                dic[values] = config.get(tab_value, values)
        if tab_value == '诊疗项目':
            for values in config.options(tab_value):
                dic[values] = config.get(tab_value, values)
        if tab_value == '材料':
            for values in config.options(tab_value):
                dic[values] = config.get(tab_value, values)
        # print(dic)
        return dic

if __name__=='__main__':
    Main()

以上代码python3.6运行通过

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值