Python 淘宝表单信息爬虫更新日志:解决mysql高版本int字段插入空值报错问题

Github项目链接:

https://github.com/Pineapple666/TaobaoSpider

一、问题描述

我一开始写爬虫的时候,数据用的是Linux虚拟机的mysql5.1上储存的(可以看做是服务器),后来又换了win10本地的mysql8.0。结果出现了如下问题:

问题1:在Navicat中建表时,设置的int字段长度为10,可一保存就自动变成了0。
在这里插入图片描述

问题2:运行程序后,出现如下错误。

在这里插入图片描述

二、问题分析

问题1

在Navicat中建表时,设置的int字段长度为10,可一保存就自动变成了0。

查了一下资料发现,从8.0.17版本开始,TINYINT, SMALLINT, MEDIUMINT, INT, and BIGINT类型的显示宽度将失效,但这并不是导致程序出错的原因。

问题2

第一行的comments,不正确的整数值?可能是我插入是数据有问题。将两个版本的表比对一下:

mysql5.1:
在这里插入图片描述
mysql8.0:

两张表全部按照comments字段进行降序排序,发现8.0的版本里comments字段没有0

查了下相关资料,发现mysql高版本在插入null值时会报错,要将值替换成NULL或0。

5.1版本测试:

建表语句:

CREATE TABLE `test`.`Untitled`  (
  `id` varchar(255) NULL,
  `brith` int(10) NULL
);

测试代码:

import pymysql

id = 'Pineapple'
brith = ''


db = pymysql.connect(host='namenode', user='root', password=None, port=3306, db='test')
cursor = db.cursor()
sql = 'INSERT INTO brith (id,brith) values(%s,%s)'
try:
    cursor.execute(sql, (id,brith))
    db.commit()
except pymysql.MySQLError as e:
    print(e.args)
    db.rollback()
db.close()

执行结果:

没有报错,空值自动转换为0
在这里插入图片描述

8.0版本测试:

建表语句同上

测试代码:

import pymysql

id = 'Pineapple'
brith = ''


db = pymysql.connect(host='localhost', user='root', password='15423824563.', port=3306, db='test')
cursor = db.cursor()
sql = 'INSERT INTO brith (id,brith) values(%s,%s)'
try:
    cursor.execute(sql, (id,brith))
    db.commit()
except pymysql.MySQLError as e:
    print(e.args)
    db.rollback()
db.close()

执行结果:

报错(1366, "Incorrect integer value: '' for column 'brith' at row 1"),插入数据失败。
在这里插入图片描述

修改代码:

import pymysql

id = 'Pineapple'
brith = ''


db = pymysql.connect(host='localhost', user='root', password='15423824563.', port=3306, db='test')
cursor = db.cursor()
sql1 = 'INSERT INTO brith (id,brith) values(%s,NULL)'
sql2 = 'INSERT INTO brith (id,brith) values(%s,0)'
try:
    cursor.execute(sql1, id)
    cursor.execute(sql2, id)
    db.commit()
except pymysql.MySQLError as e:
    print(e.args)
    db.rollback()
db.close()

执行结果:

没有报错,正确插入NULL和0
在这里插入图片描述

三、解决方法

修改MySQL类的insert方法
我没有加判断mysql版本的操作,反正空值都是要转换成0的,干脆统一一下,不管是什么版本,都判断是否有空值,有则替换成0

代码

        def insert(self, table, data):
        """
        插入数据

        :param table:
        :param data:
        :return:
        """
        keys = ', '.join(data.keys())
        values = ', '.join(['%s'] * len(data))
        # 判断是否有空值,有则替换成0
        if data.get('sales') == '':
            data['sales'] = 0
        if data.get('comments') == '':
            data['comments'] = 0
        sql_query = 'INSERT INTO %s (%s) values (%s)' % (table, keys, values)
        try:
            self.cursor.execute(sql_query, tuple(data.values()))
            self.db.commit()
        except pymysql.MySQLError as e:
            print(e.args)
            self.db.rollback()

执行结果:

没有报错,成功插入空值

在这里插入图片描述

posted @ 2022-04-06 14:58  王舰  阅读(475)  评论(0编辑  收藏  举报