python封装一个效率极高的 批量更新、插入合一的工具
我在写爬虫的时候,经常会获取大量的数据。这个时候大量数据的数据库操作如果不做一定的优化的话,将会耗费大量的时间。通过实践我发现,批量的数据操作将会极大的提高数据库操作的效率。同时,很多时候存在数据如果存在做更新操作,如果数据不存在,做插入插入操作的情况。于是我造了一个只需传入一个数组,就会自动更新或插入数据的工具。
实测以下方法操作几十万条数据只需要几秒到十几秒
以下为代码:
#说明:
#使用时直接调用saveAll方法,其他方法将被saveAll调用,你可以无视
#saveAll参数说明:
# table 表名
# datas 数据的数组 例 :[{"key1":"value1","key2":"value2"},{"key1":"value1","key2":"value2"}] 建议数组大小不要超过一千。
# searchKeys 用于确定唯一行的键的数组,如用户表的用户名,选课表的课程ID与学生ID等 例 ["user_id","class_id"]
# ifIgnoreSearchKey 是否忽略searchKey 如果你的searchKeys 是自增长的ID 你肯定不希望插入的时候插入这个字段 "1"是,"0"否
# ifNotUpdate 是否不做更新操作 如果这个设为 "0" ,datas中数据如果已在数据库中,将不会做更新操作
#getConnection 方法中的DB 是我从我的配置文件中导入的,你可以换成你的
def getConnection():conn = MySQLdb.connect(host=DB["host"],user=DB["user"],passwd=DB["passwd"],db=DB["db"],charset=DB["charset"])return conndef saveAll(table,datas,searchKeys,ifIgnoreSearchKey,ifNotUpdate):print datasconn = getConnection()cursor = conn.cursor()where = []#转义数据,避免sql发生错误for data in datas:for key in data:data[key] = MySQLdb.escape_string(str(data[key]))for searchKey in searchKeys:searchKeyDatas = []for data in datas:searchKeyDatas.append(data[searchKey])searchKeyDatasString = "`"+searchKey+"` in ('"+"','".join(searchKeyDatas)+"')"where.append(searchKeyDatasString)whereString = " AND ".join(where)selectSql = "SELECT `"+"`,`".join(searchKeys)+"` from "+table+" WHERE " + whereStringcursor.execute(selectSql)conn.commit()results = cursor.fetchall()updateData = []insertData = []existKey = []for result in results:keyValue = []for value in result:keyValue.append(str(value))existKey.append(",".join(keyValue))for data in datas:keyValue = []for key in searchKeys:keyValue.append(data[key])currentKey = ",".join(keyValue)if currentKey in existKey:updateData.append(data)else:insertData.append(data)if ifNotUpdate == "0":updateAll(updateData,table,searchKeys)insertAll(insertData,table,searchKeys,ifIgnoreSearchKey)conn.close()passdef updateAll(datas,table,searchKeys):#同时更新多条数据if len(datas) == 0:returnconn = getConnection()cursor = conn.cursor()sets = {}updateSql = "UPDATE `"+table+"` set "whereValues = []whereKey = "WHERE CONCAT(`"+"`,',',`".join(searchKeys)+"`) IN "for data in datas:whereValue = []for searchKey in searchKeys:whereValue.append(data[searchKey])whereValueString = ",".join(whereValue)whereValues.append(whereValueString)for key in data:if key in searchKeys:passelse:searchValue = []for searchKey in searchKeys:searchValue.append(str(data[searchKey]))searchValueString = ",".join(searchValue)try:sets[key][searchValueString] = data[key]except KeyError as e:sets[key] = {}sets[key][searchValueString] = data[key]searchKeysString = "(`"+"`,',',`".join(searchKeys)+"`)"whereValuesString = "('"+"','".join(whereValues)+"')"setStringArray = []for key1 in sets:setString = ""for key2 in sets[key1]:if setString == "":setString = "`"+key1+"` = CASE WHEN (CONCAT"+searchKeysString+"='"+key2+"') THEN '"+sets[key1][key2]+"'"else:setString = setString + " WHEN (CONCAT"+searchKeysString+"='"+key2+"') THEN '"+sets[key1][key2]+"'"setString += " END "setStringArray.append(setString)setStrings = ",".join(setStringArray)whereStrings = whereKey + whereValuesStringupdateSql += setStringsupdateSql += whereStringsprint updateSqltry:cursor.execute(updateSql)result = cursor.fetchall()except Exception as e:print e.messageprint updateSqlconn.commit()conn.close()def insertAll(datas,table,searchKeys,ifIgnoreSearchKey):#多条数据同时添加if len(datas) == 0:returnconn = getConnection()cursor = conn.cursor()keys=[]for key in datas[0]:if key not in searchKeys or ifIgnoreSearchKey!= "1":keys.append(key)insertSql = "INSERT INTO "+table+" (`"+"`,`".join(keys)+"`) VALUES "valueStrings = []for data in datas:value = []for key in keys:value.append(data[key])valueString = "('" + "','".join(value) + "')"valueStrings.append(valueString)insertSql += ",".join(valueStrings)print insertSqltry:cursor.execute(insertSql)conn.commit()conn.close()except Exception as e:print insertSqlprint e.message
如果有帮到您,打个赏呗
python封装一个效率极高的 批量更新、插入合一的工具相关推荐
- 论文浅尝 | 一种嵌入效率极高的 node embedding 方式
论文笔记整理:叶群,浙江大学计算机学院,知识图谱.NLP方向. 会议:WSDM 2019 链接:https://dl.acm.org/citation.cfm?id=3290961 Motivatio ...
- python封装一个requests请求
python封装一个requests请求 更新:https://blog.csdn.net/qq_42846555/article/details/126401051 from requests im ...
- python socket能做什么_用python写一个聊天小程序!和女朋友的专属聊天工具!
原标题:用python写一个聊天小程序!和女朋友的专属聊天工具! 1.UDP简介 Internet协议集支持一个无连接的传输协议,该协议称为用户数据报协议(UDP).UDP为应用程序提供了无需建立就可 ...
- 使用Python 封装一个简单的Mysql工具类
pymysql操作mysql,虽然简单,但每次都要链接数据库,获取游标,关闭游标,关闭链接.这些操作无技术含量,还要重复编写!!想一想不如封装一个DBUtil,来提高开发效率. 要编写工具类首先要把公 ...
- 用python封装一个学生类
# 封装一个学生类,(自行分辨定义为类属性还是实例属性) # 属性:身份(学生),姓名,年龄,性别,英语成绩,数学成绩,语文成绩, 职责. # 如果是类属性请提前定义, # 如果是实例属性请初始化 ...
- excel 复制数据 sql server 粘贴_一个Excel妙招,一个SQL技巧,解决批量数据插入问题
#Excel技巧# #数据库# #MySQL# 业务背景 不知道您在工作中有没有遇到过这样几种情况: 业务定期给你一批数据结构相同的名单或者数据,要求你插入到库里并进行处理. 机器学习指标加工时,一个 ...
- mysql allowmultiqueries=true_Mysql批量更新的一个坑-allowMultiQueries=true允许批量更新(转)...
实际上,我们经常会遇到这样的需求,那就是利用Mybatis批量更新或者批量插入,但是,实际上即使Mybatis完美支持你的sql,你也得看看你说操作的数据库是否支持,而阿福,最近就遇到这样的一个坑. ...
- Mysql批量更新的一个坑-allowMultiQueries=true允许批量更新
前言 实际上,我们经常会遇到这样的需求,那就是利用Mybatis批量更新或者批量插入,但是,实际上即使Mybatis完美支持你的sql,你也得看看你说操作的数据库是否支持,而阿福,最近 ...
- spring boot- JdbcTemplate、NamedParameterJdbcTemplate基本使用(批量更新插入)
文章目录 第一部分:JdbcTemplate 一.了解JdbcTemplate 二.JdbcTemplate使用步骤 1. sql直接插入一条数据 2. 通过Statement方式批量插入[推荐] 批 ...
最新文章
- java.util.concurrent.Callable 接口 源码
- [LeetCode]ZigZag Conversion
- java有 号_JAVA揭竿而起总要有名号
- 重启IIS和SqlServer的命令行
- 如何做一个合格的面试官?
- 17.立体匹配——匹配两个图 Matlab实战,立体效果_3
- Makingware调用静态块,实现自定义html内容的常用方法(不需要修改模版部分)...
- egon说一切皆对象--------面向对象进阶紫禁之巅
- null value in entry: destinationDir=null
- 女神节福利来了!(自动驾驶/三维重建/SLAM/点云/标定/深度估计/3D检测)
- 使用Tftpd64收集交换机日志
- Ubuntu20.04下opencv的安装
- 网络抓取ts文件转mp4_TS格式的视频文件怎么转换成mp4文件。
- validation
- 漂泊的旅途,云淡风轻
- 华为交换机命令 端口速率_华为S5700交换机的端口QOS限速问题
- 链接、图像、列表、计数器
- 2019北航计科保研夏令营(非优营)
- tensorflow踩坑
- python-23-递归:这帮小兔崽子
热门文章
- 成功解决 .Quit() File COMObject InternetExplorer.Application, line 2, in Quit pywintypes.com_error
- 成功解决AttributeError: 'map' object has no attribute 'items'
- TF:利用TF的train.Saver将训练好的W、b模型文件保存+新建载入刚训练好模型(用于以后预测新的数据)
- JAVA_OA(十四):SSM练手项目bug-Oracle分页web页面无法转到下一页
- GridSearchCV.grid_scores_和mean_validation_score报错
- 机器学习-特征工程中的特征选择
- Spring使用笔记(一)Spring简介
- es6 - foreach
- 使用dtd--属性声明
- 提高SQL语句的性能