`

MySQLdb+动态组合批量插入sql+防重复(时间和空间代价)

阅读更多

问题描述:工作上有多张带中文名称(name)和英文名称(name_en)两个字段的表(name可以为null,有索引,数据量从十万到千万之间)供公司网站后台使用,由于使用人员添加数据的时候,没有很好的检查机制,会造成一个中文名对应多个英文名称情况发生,现在需要定时将多张表的数据导入一张新的表,保证一个中文名称对应一个英文名称(name不可以为null,有唯一性索引)

 

环境工具:python2.6 windowsXP

 

解决过程:1. 新建的表里面,中文名称(name)是唯一性索引unique,保证一个中文名称对应一个英文名称,有两种方案,第一种,在插入之前,用python的逻辑检查数据的重复情况;第二种,在插入之时,用sql自身的机制检查重复性

 

                   2. 考虑第二种方案,sql避免重复插入,有很多种如下

ignore关键字

根据(主键primary字段、唯一索引unique字段)区分记录的唯一性

      insert ignore into table_name(name, name_en) values('全国花生油平均价格', 'price of oil')

执行结果,name、name_en始终保持第一次插入的值,第一次插入时,返回影响行数为1,之后插入时,忽略insert,返回影响行数0

replace关键字

根据(主键primary字段、唯一索引unique字段)区分记录的唯一性

       replace into table_name(name, name_en) values('全国花生油平均价格', 'price of oil')

执行结果,name保持第一次插入的值,name_en更新为最后一次插入的值,第一次插入时,返回影响行数1,之后再插入时,先delete旧行,再insert新行,返回影响行数2

on duplicate key update关键字根据(主键primary字段、唯一索引unique字段)区分记录的唯一性

        insert into table_name(name, name_en) values('全国花生油平均价格', 'price of oil') on duplicate key update name_en = 'price of oil'

执行结果,name保持第一次插入的值,name_en更新为最后一次插入的值,第一次插入时,返回影响行数1,之后再插入时,update区分唯一性字段以外的其他字段,返回影响行数1

 

        考虑到数据的最新价值和效率问题,采用on duplicate key update关键字,但是在使用过程中,用python组合sql语句

insert into table_name(name, name_en) values(%s, %s) on duplicate key update name_en = %s

批量整合参数时,配四个参数,始终报错bug:not all arguments converted during string formatting,如果配三个参数,也报错SQL syntax语法问题

        通过报错信息回溯,Python26/Lib/site-packages/MySQLdb/cursors.py里面

提取参数的正则表达式

       restr = (r"\svalues\s*"
        r"(\(((?<!\\)'[^\)]*?\)[^\)]*(?<!\\)?'"
        r"|[^\(\)]|"
        r"(?:\([^\)]*\))"
        r")+\))")

def executemany(self, query, args):里面有

        m = insert_values.search(query)

这里只提取了values(%s, %s, %s)里面的参数,导致条件参数始终无法匹配上,报错;在此,改用

replace into table_name(name, name_en) values(%s, %s)

或者

insert into table_name(name, name_en) values(%s, %s) on duplicate key update name_en = values(name_en)

 

                  3. 考虑第三种方案,python逻辑处理重复问题,由于destination表和source表的数据量都很大,因此在判断数据是否重复的比较时,要考虑时间和空间的问题,也有两种方案

in关键字

select name, name_en from source #取源数据

result1 = dict(name, name_en)

select name, name_en from destination #取目的数据

result2 = dict(name, name_en)  

for name, name_en in result1:

     if name, name_en in result2: #检测源数据是否在目的数据

          update destination set name_en = %s where name = %s #在,update

     else:

          insert into destination(name, name_en) values(%s, %s) #不在,insert

分段排序orderby limit段外递增推进 binarySearch段内二分查找,段内丢弃result1 = []

result2 = []

currpage = 0

for i in range(pages1):

    startindex = i * pagenum

    select name, name_en from source where name_en is not null order by name limit startindex, pagenum

    result1 = result1.extends(dict(name, name_en))

    for name, name_en in result1:

        if name, name_en in result2: #检测源数据是否在目的数据

             update destination set name_en = %s where name = %s #在,update

             result2 = result2[result2.index((name,name_en))+1:len(result2)] #段内丢弃

             result1.remove(result1.index((name,name_en))) #删除存在元素

        else:

              for j in ranges(currpage, pages2): #段外递增推进

                   startindex = j * pagenum            

                   select name, name_en from source where name_en is not null order by name limit startindex, pagenum

                   result2 = dict(name, name_en)

                   if name, name_en in result2:

                       update destination set name_en = %s where name = %s #在,update

                       result2 = result2[result2.index((name,name_en)):len(result2)] #段内丢弃

                       result1.remove(result1.index((name,name_en))) #删除存在元素

                       currpage=j 段号增长

                       break

if result1:

      for name, name_en in result1:

            insert into destination(name, name_en) values(%s, %s) #不在,insert

 

分享到:
评论

相关推荐

    毕业设计 基于Python+MySQL+HTML开发的壁纸共享网站源码+使用说明+数据库sql.zip

    打开 doc/database_design.sql ,该文件中的数据是mysql数据库表的创建代码,将其中的代码复制到mysql客户端执行,便能够创建出本网站所需要的数据库和表。 修改conf目录下的conf.py 文件,该文件下有一个CONF的变量...

    mysqldb.sql

    mysql数据库设计文件 mysql数据库设计文件 mysql数据库设计文件

    MySQLDB.sql

    MySQLDB.sql

    MySQLdb(64位)

    MySQLdb是Python编程语言中一个常用的数据库连接库,专门用于与MySQL数据库进行交互。它实现了Python的DB-API(PEP 249),使得Python程序员能够以简洁、高效的语法访问和操作MySQL数据库。这个包是专为64位操作系统...

    python mysqldb

    `libmmd.dll`和`libguide40.dll`是两个动态链接库文件,它们是MySQL Connector/C(MySQL的C语言接口)的一部分,用于在Python中进行MySQL数据库操作。`libmmd.dll`通常涉及到MySQL的多线程支持,而`libguide40.dll`...

    Mysqldb-Python3.*

    5. **执行SQL**:编写SQL语句,使用`cursor.execute(sql)`执行,可以进行插入、更新、查询和删除操作。 ```python # 插入 sql_insert = "INSERT INTO user (name, created) VALUES (%s, %s)" param_insert = ("ccc...

    MySQLdb,python

    在描述中提到的`__init__.py`和`converters.py`是MySQLdb库中的两个关键文件。 `__init__.py`是Python包的初始化文件,它的存在标识了当前目录应该被视为一个Python包。在MySQLdb这个包中,`__init__.py`通常包含了...

    MySQLdb-Python

    MySQLdb-Python是Python编程语言中用于连接MySQL数据库的一个重要模块。这个模块为Python程序员提供了一个接口,使得他们能够方便地在Python程序中操作MySQL数据库,执行SQL查询,管理数据等任务。它基于DB-API...

    MysqlDB pymysql操作类库.py.zip

    MySQLDB是Python编程语言中用于连接和操作MySQL数据库的一个接口,而pymysql则是MySQLDB的一个替代品,它是一个纯Python实现的MySQL驱动程序。在Python中,使用这些库可以方便地进行数据库的CRUD(创建、读取、更新...

    MySQLdb 1.2.4b4 documentation

    MySQLdb 1.2.4b4是该模块的一个版本,它提供了稳定性和兼容性的改进,使得Python开发者能够更高效地与MySQL数据库进行交互。 1. **MySQLdb模块介绍** MySQLdb是基于`mysql-connector-python`和`Python C API`构建...

    MySQLDB1.2.5

    连接MySQLdb1-MySQLdb-1.2.5.zip MySQLdb1-MySQLdb-1.2.5.zip MySQLdb1-MySQLdb-1.2.5.zip MySQLdb1-MySQLdb-1.2.5.zip

    mysqldb64位

    1. `_mysql.pyd`:这是Python动态链接库文件,是MySQLdb的核心组件,实现了Python和MySQL之间的接口。 2. `setup.py`:这是一个Python脚本,用于安装MySQLdb到你的Python环境中,通过执行`python setup.py install`...

    python的64位和32位mysqldb库

    mysqldb库提供了Python接口,使得Python程序员可以方便地执行SQL查询、创建表、插入数据、更新记录等操作。 在使用mysqldb时,你需要导入模块并建立连接,如下所示: ```python import MySQLdb conn = MySQLdb....

    2021_w_.1.python 驱动MySQLdb(create_engine)代码.pdf

    在代码的末尾,定义了SQL查询字符串`sql_str_1`和`sql_str_2`,它们可以被`cur_sql`或`read_sql_str`函数使用,以从数据库中获取数据。 总之,这段代码展示了如何使用Python连接MySQL数据库,执行SQL查询,读取和...

    PyPI 官网下载 | mysqldb-rich-2.7.tar.gz

    6. **性能优化**:通过预编译SQL语句和批量插入等功能,提升了数据库操作的性能。 7. **错误处理**:提供更丰富的错误信息和异常类型,帮助开发者更快定位问题。 8. **日志记录**:允许用户自定义日志级别和输出...

    Python MySQLdb 执行sql语句时的参数传递方式

    使用MySQLdb连接数据库执行sql语句时,有以下几种传递参数的方法。 1.不传递参数 conn = MySQLdb.connect(user=root,passwd=123456,host=192.168.101.23,db=cmdb) orange_id = 98 sql = select * from orange where...

    python-MySQLdb安装包

    这个包里有两个包,都可以用来在windows上安装python-MySQLdb,选择其中一种就可以!我比较喜欢用-master那个包,因为只要解压后执行python setup.py install就可以了。另一个包在安装时若出现找不到python2.7的安装...

    离线安装python2的MySQLdb

    Python的MySQLdb模块是Python连接MySQL数据库的一个重要接口,它为Python程序员提供了与MySQL数据库交互的能力。在一些没有网络或者网络环境受限的情况下,离线安装MySQLdb就显得尤为重要。下面我们将详细探讨如何在...

Global site tag (gtag.js) - Google Analytics