Python批量处理Excel数据后,导入SQL Server

本文涉及的产品
云数据库 RDS SQL Server,基础系列 2核4GB
RDS SQL Server Serverless,2-4RCU 50GB 3个月
推荐场景:
简介: Python批量处理Excel数据后,导入SQL Server

简说Python,号主老表,Python终身学习者,数据分析爱好者,从18年开始分享Python知识,原创文章227篇,写过Python、SQL、Excel入门文章,也写过Web开发、数据分析文章,老表还总结整理了一份2022Python学习资料和电子书资源,关注后私信回复:2022 即可领取。

1、前言

紧接昨天的文章Windows下载安装配置SQL Server、SSMS,使用Python连接读写数据,我们已经安装和配置好了sqlserver,也成功测试了如何利用Python连接、读写数据到数据库。

今天我们正式开始怼需求:有很多Excel,需要批量处理,然后存入不同的数据表中。

2、开始动手动脑

2.1 拆解+明确需求

1) excel数据有哪些需要修改?

  • 有一列数据DocketDate是excel短时间数值,需要转变成正常的年月日格式;
    eg. 44567 --> 2022/1/6
  • 部分数据需要按SOID进行去重复处理,根据DocketDate保留最近的数据;
  • 有一列数据需要进行日期格式转换。
    eg. 06/Jan/2022 12:27 --> 2022-1-6

主要涉及:日期格式处理、数据去重处理

2) 每一个Excel都对应一个不同数据表吗?表名和Excel附件名称是否一致?

  • 有些Excel对应的是同一个表,有些是单独的
  • 表名和Excel附件名称不一致,不过是有对应关系的
    eg. 附件test1 和 test2 对应表 testa,附件test3 对应 testb

主要涉及:数据合并处理

2.2 安装第三方包

pip3 install sqlalchemy pymssql pandas xlrd xlwt
  • sqlalchemy:可以将关系数据库的表结构映射到对象上,然后通过处理对象来处理数据库内容;
  • pymssql:python连接sqlserver数据库的驱动程序,也可以直接使用其连接数据库后进行读写操作;
  • pandas:处理各种数据,内置很多数据处理方法,非常方便;
  • xlrd xlwt:读写excel文件,pandas读写excel会调用他们。

导入包:

import pandas as pd
from datetime import date, timedelta, datetime
import time
import os
from sqlalchemy import create_engine
import pymssql

2.3 读取excel数据

读取数据比较简单,直接调用pandas的read_excel函数即可,如果文件有什么特殊格式,比如编码,也可以自定义设置。

# 读取excel数据
def get_excel_data(filepath):
    data = pd.read_excel(filepath)
    return data

2.4 特殊数据数据处理

1)日期天数转短日期

这个有一定难度,excel里直接转很简单,直接选中需要转的数据,然后在开始-数据格式栏选择短日期即可。

image.png

当时第一眼不知道其中的转换规律,搜索了很久,也没发现有类似问题或说明,首先肯定不是时间戳,感觉总有点关系,最后发现是天数,计算出天数计算起始日期就可以解决其他数据转变问题啦。

首先我们要判断空值,然后设置日期天数计算起始时间,利用datetime模块的timedelta函数将时间天数转变成时间差,然后直接与起始日期进行运算即可得出其代表的日期。

# 日期天数转短日期
def days_to_date(days):
    # 处理nan值
    if pd.isna(days):
        return 
    #  44567  2022/1/6
    # 推算出 excel 天数转短日期 是从1899.12.30开始计算
    start = date(1899,12,30) 
    # 将days转换成 timedelta 类型,可以直接与日期进行计算
    delta = timedelta(days)
    # 开始日期+时间差 得到对应短日期
    offset = start + delta
    return offset

这里比较难想的就是天数计算起始日期,不过想明白后,其实也好算,从excel中我们可以直接将日期天数转成短日期,等式已经有了,只有一个未知数x,我们只需列一个一元一次方程即可解出未知数x。

from datetime import date, timedelta
date_days = 44567
# 将天数转成日期类型时间间隔
delta = timedelta(date_days)
# 结果日期
result = date(2022,1,6)
# 计算未知的起始日期
x = result - delta
print(x)
'''
输出:1899-12-30
'''

2)将日期中的英文转成数字

最开始我想的是使用正则匹配,将年月日都在取出来,然后将英文月份转变成数字,后来发现日期里可以直接识别英文的月份。

代码如下,首先将字符串按格式转变成日期类型数据,原数据为06/Jan/2022 12:27(数字日/英文月/数字年 数字小时:数字分钟),按日期格式化符号解释表中对应关系替换即可。

# 官方日期格式转换成常见格式
def date_to_common(time):
    # 处理nan值
    if pd.isna(time):
        return 
    # 06/Jan/2022 12:27  2022-1-6
    # 测试 print(time,':', type(time))
    # 将字符串转成日期
    time_format = datetime.strptime(time,'%d/%b/%Y %H:%M') 
    # 转换成指定日期格式
    common_date = datetime.strftime(time_format, '%Y-%m-%d') 
    return common_date

image.png

日期格式化符号解释表

@CSDN-划船的使者

3)按订单编号SOID去重

这里去重复除了按指定列去重外,还需要按日期保留最新数据。

我的想法是,首先调用pandas的sort_values函数将所有数据根据日期列进行升序排序,然后,调用drop_duplicates函数指定按SOID列进行去重,并指定keep值为last,表示重复数据中保留最后一行数据。

代码如下:

# 去除重复值 SOID重复 按日期去除最早的数据
def delete_repeat(data):
    # 先按日期列 Docket Rec.Date & Time 排序 默认降序  保证留下的日期是最近的
    data.sort_values(by=['Docket Rec.Date & Time'], inplace=True)
    # 按 SOID 删除重复行
    data.drop_duplicates(subset=['SOID #'], keep='last', inplace=True)
    return data

2.5 其他需求

多个Excel数据对应一张数据库的表

可以写一个字典,来存储数据库表和对应Excel数据名称,然后一个个存储到对应的数据库表中即可(或者提前处理好数据后,再合并)。

  • 合并同类型Excel表
# 相同表合并数据 传入合并excel列表
def merge_excel(elist, files_path):
    data_list = [get_excel_data(files_path+i) for i in elist]
    data = pd.concat(data_list)
    return data

这里传入同一类型Excel文件名列表(elist)和数据存储文件夹绝对/相对路径(files_path)即可,通过文件绝对/相对路径+Excel文件名即可得到Excel数据表文件的绝对/相对路径,再调用get_excel_data函数即可读取出数据。

遍历读取Excel表数据利用了列表推导式,最后利用pandas的concat函数即可将对应数据进行合并。

  • 数据存储到sqlserver
# 初始化数据库连接引擎
# create_engine("数据库类型+数据库驱动://数据库用户名:数据库密码@IP地址:端口/数据库",其他参数)
engine = create_engine("mssql+pymssql://sa:123456@localhost/study?charset=GBK")
# 存储数据
def data_to_sql(data, table_naem, columns):
    # 再对数据进行一点处理,选取指定列存入数据库
    data1 = data[columns]
    # 第一个参数:表名
    # 第二个参数:数据库连接引擎
    # 第三个参数:是否存储索引
    # 第四个参数:如果表存在 就追加数据
    t1 = time.time()  # 时间戳 单位秒
    print('数据插入开始时间:{0}'.format(t1))
    data1.to_sql(table_naem, engine, index=False, if_exists='append')
    t2 = time.time()  # 时间戳 单位秒
    print('数据插入结束时间:{0}'.format(t2))
    print('成功插入数据%d条,'%len(data1), '耗费时间:%.5f秒。'%(t2-t1))

sqlalchemy+pymssql连接sqlserver的时候注意坑:要指定数据库编码,slqserver创建的数据库默认是GBK编码,关于sqlserver安装使用可以查看文章Windows下载安装配置SQL Server、SSMS,使用Python连接读写数据

2.6 完整调用代码

'''
批量处理所有excel数据
'''
# 数据文件都存储在某个指定目录下,如:
files_path = './data/'
bf_path = './process/'
# 获取当前目录下所有文件名称
# files = os.listdir(files_path)
# files
# 表名:附件excel名
data_dict = {
    'testa': ['test1.xls', 'test2.xls'], 
    'testb': ['test3.xls'], 
    'testc': ['test4.xls']
}
# 选取附件中的指定列,只存入指定列数据
columns_a = ['S/No', 'SOID #', 'Current MileStone', 'Store In Date Time']
columns_b = ['Received Part Serial No', 'Received Product Category', 'Received Part Desc']
columns_c = ['From Loc', 'Orig Dispoition Code']
columns = [columns_a, columns_b, columns_c]
flag = 0  # 列选择标记
# 遍历字典 合并相关excel 然后处理数据后,存入sql
for k,v in data_dict.items():
    table_name = k
    data = merge_excel(v, files_path)
    # 1、处理数据
    if 'SOID #' not in data.columns:
        # 不包含要处理的列,则直接简单去重后、存入数据库
        data.drop_duplicates(inplace=True)
    else:
        # 特别处理数据
        data = process_data(data)
    # 2、存储数据
    # 保险起见 本地也存一份
    data.to_excel(bf_path+table_name+'.xls')
    # 存储到数据库
    data_to_sql(data, table_name, columns[flag])
    flag+=1

本文点赞过20,最近开源本文所有相关数据和代码。

3、后言后语

欢迎大家提需求呀,必须要有:明确的需求(列点)+ 有示例数据(打包发送)。

--xxx-xxxx需求.zip
----数据文件
----需求说明文件
----其他补充文件

可以将需求和对应的需求说明+示例数据压缩包文件发送到我的邮箱zjhbrief@163.com

最近过年在家,时间相对充足,欢迎交流~

坚持 and 努力 :终有所获。

思想很复杂,

实现很有趣,

只要不放弃,

终有成名日。

—《老表打油诗》

相关实践学习
使用SQL语句管理索引
本次实验主要介绍如何在RDS-SQLServer数据库中,使用SQL语句管理索引。
SQL Server on Linux入门教程
SQL Server数据库一直只提供Windows下的版本。2016年微软宣布推出可运行在Linux系统下的SQL Server数据库,该版本目前还是早期预览版本。本课程主要介绍SQLServer On Linux的基本知识。 相关的阿里云产品:云数据库RDS SQL Server版 RDS SQL Server不仅拥有高可用架构和任意时间点的数据恢复功能,强力支撑各种企业应用,同时也包含了微软的License费用,减少额外支出。 了解产品详情: https://www.aliyun.com/product/rds/sqlserver
相关文章
|
3月前
|
SQL 自然语言处理 数据库
【Azure Developer】分享两段Python代码处理表格(CSV格式)数据 : 根据每列的内容生成SQL语句
本文介绍了使用Python Pandas处理数据收集任务中格式不统一的问题。针对两种情况:服务名对应多人拥有状态(1/0表示),以及服务名与人名重复列的情况,分别采用双层for循环和字典数据结构实现数据转换,最终生成Name对应的Services列表(逗号分隔)。此方法高效解决大量数据的人工处理难题,减少错误并提升效率。文中附带代码示例及执行结果截图,便于理解和实践。
|
1月前
|
SQL 数据挖掘 关系型数据库
【SQL 周周练】一千条数据需要做一天,怎么用 SQL 处理电表数据(如何动态构造自然月)
题目来自于某位发帖人在某 Excel 论坛的求助,他需要将电表缴费数据按照缴费区间拆开后再按月份汇总。当时用手工处理数据,自称一千条数据就需要处理一天。我将这个问题转化为 SQL 题目。
91 12
|
1月前
|
SQL 数据采集 资源调度
【SQL 周周练】爬取短视频发现数据缺失,如何用 SQL 填充
爬虫爬取抖音和快手的短视频数据时,如果遇到数据缺失的情况,如何使用 SQL 语句完成数据的补全。
63 5
|
3月前
|
Shell Python
[oeasy]python072_名字空间是怎么玩的_from_import_as_导入_namespace
本文介绍了Python中名字空间和模块导入的使用方法。主要内容包括: 1. **回忆上次内容**:回顾了之前导入系统模块(如`__hello__`、`time`)和自定义模块(如`my_file`),并介绍了如何导入和使用模块中的变量。 2. **从shell开始**:展示了如何在命令行中编辑和切换文件,以及如何通过`import`语句引入模块。 3. **修改oeasy.py**:演示了如何通过`import my_file`导入模块,并将模块中的`pi`赋值给本地变量`pi`。 4. **locals()函数**:解释了如何使用`locals()`查看当前作用域内的本地变量及其值。
72 8
|
3月前
|
人工智能 自然语言处理 Shell
[oeasy]python070_如何导入模块_导入模块的作用_hello_dunder_双下划线
本文介绍了如何在Python中导入模块及其作用,重点讲解了`__hello__`模块的导入与使用。通过`import`命令可以将外部模块引入当前环境,增强代码功能。例如,导入`__hello__`模块后可输出“Hello world!”。此外,还演示了如何使用`help()`和`dir()`函数查询模块信息,并展示了导入多个模块的方法。最后,通过一个实例,介绍了如何利用`jieba`、`WordCloud`和`matplotlib`模块生成词云图。总结来说,模块是封装好的功能部件,能够简化编程任务并提高效率。未来将探讨如何创建自定义模块。
56 8
|
4月前
|
SQL 关系型数据库 MySQL
基于SQL Server / MySQL进行百万条数据过滤优化方案
对百万级别数据进行高效过滤查询,需要综合使用索引、查询优化、表分区、统计信息和视图等技术手段。通过合理的数据库设计和查询优化,可以显著提升查询性能,确保系统的高效稳定运行。
148 9
|
3月前
|
SQL 容灾 关系型数据库
阿里云DTS踩坑经验分享系列|DTS打通SQL Server数据通道能力介绍
SQL Server 以其卓越的易用性和丰富的软件生态系统,在数据库行业中占据了显著的市场份额。作为一款商业数据库,外部厂商在通过解析原生日志实现增量数据捕获上面临很大的挑战,DTS 在 SQL Sever 数据通道上深研多年,提供了多种模式以实现 SQL Server 增量数据捕获。用户可以通过 DTS 数据传输服务,一键打破自建 SQL Server、RDS SQL Server、Azure、AWS等他云 SQL Server 数据孤岛,实现 SQL Server 数据源的流动。
210 0
阿里云DTS踩坑经验分享系列|DTS打通SQL Server数据通道能力介绍
|
7月前
|
SQL 存储 缓存
SQL Server 数据太多如何优化
11种优化方案供你参考,优化 SQL Server 数据库性能得从多个方面着手,包括硬件配置、数据库结构、查询优化、索引管理、分区分表、并行处理等。通过合理的索引、查询优化、数据分区等技术,可以在数据量增大时保持较好的性能。同时,定期进行数据库维护和清理,保证数据库高效运行。
174 4
|
7月前
|
SQL 数据挖掘 Python
数据分析编程:SQL,Python or SPL?
数据分析编程用什么,SQL、python or SPL?话不多说,直接上代码,对比明显,明眼人一看就明了:本案例涵盖五个数据分析任务:1) 计算用户会话次数;2) 球员连续得分分析;3) 连续三天活跃用户数统计;4) 新用户次日留存率计算;5) 股价涨跌幅分析。每个任务基于相应数据表进行处理和计算。
|
SQL Python 数据库
笨办法学 Python · 续 练习 40:SQL 读取
练习 40:SQL 读取 原文:Exercise 40: Reading with SQL 译者:飞龙 协议:CC BY-NC-SA 4.0 自豪地采用谷歌翻译 在 CRUD 矩阵中,你只知道“创建”。
1029 0

推荐镜像

更多