Python 向db2数据库中批量插入大量数据(1w条左右)

网上关于python操作db2的文章很少,特此记录。

目录

  • 1. 最终解决方案
  • 2. 探索1:load & import
  • 3. 探索2:to_sql
  • 4. 探索3: excutemany(sql,param)
  • 5. 遇到的bug

环境

  1. Python 3.8.6
  2. ibm_db_sa 0.3.7
  3. ibm-db 3.0.4
  4. sqlalchemy 1.4.7

1. 最终解决方案

采用拼接字符串的方法,把要批量插入的数据拼接成insert into table values (),...,(),()这种形式。

 def save_batch_db2(self, ssql, df):
        """ 向db2数据库中批量导入数据
        :param df:DataFrame
        :param ssql:提供拼接的sql的前半部分 e.g. insert into table values   
        """
        tuplesValues = [tuple(x) for x in df.values]
        # 此时的sqlStr: [('colunm1','colunm1','colunm1'),(...),(...)]
        sqlStr = str(tuplesValues)
        # 截取
        sqlStr = sqlStr[1:len(sqlStr) - 1]
        #拼接并执行
        sql3 = ssql + sqlStr
        self.db_gp_connect.insert(sql3)

用时3.5秒左右,未截图。

由于之前未接触过python,加之python处理db2网络上教程很少。探索的过程中也出现了各式各样的bug。

2. 探索1:load & import

我一开始的思路是先将数据导入csv文件中,然后再将csv文件转储到db2中,再通过python脚本调用命令行执行csv导入db2的命令。通过百度得知loadimport可以完成这个工作。前者比后者效率更高。代码我也写出来了,如下

LOAD client FROM filePath/xxx.csv of del INSERT INTO tableName
IMPORT from filePath/xxx.csv of del INSERT INTO tableName

但是这个行不通,原因如下:

  1. python写脚本调用db2命令行我没写过,不擅长,学习成本过高。
  2. 运行程序的服务器上没安装db2,无法运行db2命令行。
  3. 数据库和程序在不同服务器上,不晓得这个命令能不能用。

3. 探索2:to_sql

这个最终实现了,代码如下:

import sqlalchemy
from sqlalchemy import *
import ibm_db
import ibm_db_sa

def func(self,param1,...):
    engine = create_engine("db2+ibm_db://user:pass@host:50000/database")
    df.to_sql(name='tableName', chunksize=1000, con=engine, if_exists='append', index=False)

插入大约5400条数据用时: 7.996s计算用时

4. 探索3: excutemany(sql,param)

param是需要批量插入的数据,形式为列表或者元组。通过读源码得知这个内部其实也是调用的excute一条一条插入数据,效率比前面的方法差距太大。这个也实现了,代码简单就不贴了。(其实是代码忘记保存了,懒得重写了,哈哈哈)

5. 遇到的bug

SQLCODE=-803
通过查询得知是主键冲突。检查sql,发现是读取数据的时候误操作导致的,修改后程序正常运行。

写这篇博客的时候,我是非常开心的,因为解决了一个困扰我很久的bug,解决了批量插入db2数据库这一技术问题。排查主键重复这个bug的时候写出来很轻松。实际上花了不少时间。由于粗心边界值判断多一个‘=’导致分数为60分的数据出现两行。
由此得出两点结论:
1.写代码要细心
2.认识是螺旋上升的,不要气馁


凡事多问自己一句:不试试怎么知道呢?

你可能感兴趣的:(Python,python,db2)