MYSQL 批量插入操作

对数据库的增删改查平时的工作中用的比较多,也比较熟悉。忽然发现都没有使用过 insert 操作,因此在学习 python 的过程中,通过 mysql.connector44w行 的 ip地址记录进行数据库批量插入工作。

另:简书不支持图片外链,我没找到什么好方法来上传图片,如果有需要看图片的,可以移步到我的博客中去看,本篇文章的博客地址在本文末。


步骤分为以下五步:

1. 数据格式整理
2. 创建表
3. 连接表
4. 读取本地文件数据 
5. 批量写入

数据格式整理

首先查看所拿到的数据,并整理:
分别在终端中使用 head ipdata.csvtail ipdata.csv 来查看文件的头部和尾部数据,对其规律进行分析。

:~/Documents/study/NiuCodeLesson/insertSQL% head ipdata.csv
1,0.0.0.0,0.255.255.255,IANA,保留地址
2,1.0.0.0,1.0.0.255,澳大利亚,CZ88.NET
3,1.0.1.0,1.0.3.255,福建省,电信
4,1.0.4.0,1.0.7.255,澳大利亚,CZ88.NET
5,1.0.8.0,1.0.15.255,广东省,电信
6,1.0.16.0,1.0.31.255,日本,Beacon服务器
7,1.0.32.0,1.0.63.255,广东省,电信
8,1.0.64.0,1.0.127.255,日本,広島県中区大手町Energia通信公司
9,1.0.128.0,1.0.255.255,泰国,CZ88.NET
10,1.1.0.0,1.1.0.255,福建省,电信
:~/Documents/study/NiuCodeLesson/insertSQL% tail ipdata.csv
444954,223.255.252.0,223.255.253.255,福建省,电信
444955,223.255.254.0,223.255.254.255,新加坡,滨海湾金沙私人有限公司
444956,223.255.255.0,223.255.255.255,澳大利亚,CZ88.NET
444957,224.0.0.0,224.255.255.255,IANA,CZ88.NET
444958,225.0.0.0,239.255.255.255,IANA保留地址,用于多点传送
444959,240.0.0.0,247.255.255.255,IANA保留地址,CZ88.NET
444960,248.0.0.0,248.255.255.255,IANA保留地址,CZ88.NET
444961,249.0.0.0,254.255.255.255,IANA保留地址,CZ88.NET
444962,255.0.0.0,255.255.254.255,CZ88.NET,
444963,255.255.255.0,255.255.255.255,纯真网络,2014年10月25日IP数据

查看后我们可以大致将数据分为 5 列,「序号」,「起始IP」,「终止IP」,「所在地」,「运营商」。

创建表

经过格式的分析,我们就可以创建一个表的结构了。
注:事实上分析数据规律比建表要重要的多,因为本文重点不在此处,所以概过。

首先通过 navicat 创建本地的数据库。数据库格式如下图:

[图片上传失败...(image-e6819d-1518059726027)]

连接表

首先连接本地数据库

因为我的表示创建在本地数据库下的,连接的库的时候不需要添加 host 参数
连接本地数据库的代码如下:

conn = mysql.connector.connect(user='root', password='admin', database='test')

连接远程数据库的代码如下:

conn = connection.MySQLConnection(host=host_d, user=user_d, password=password_d, database=database_d)

读取 csv 数据文件

一般来说,读取文件的方法有两种;推荐以下方式来读取文件,可以避免忘记关闭文件句柄的尴尬:

    with open('./ipdata.csv', 'r') as f:
        lines = f.readlines()

读取文件格式采坑

在读取文件的过程中发现了报错。

报错信息:

UnicodeDecodeError: 'ascii' codec can't decode byte 0xe4 in position 29: ordinal not in range(128)

原因分析:

出错的原因是因为 csv 内的编码方式与程序环境编码方式不一致所致。csv 的编码格式是 gbk, 只要能够用 unicode 编码格式处理读取进来的数据就解决了。

搜索解决方案:

自从上次瞎捷豹连续操劳后,已经很久没有让它出门了,这次又要有劳它了。
经过搜索后,发现很多方案:

方案一 代码头部申明编码

有两种写法,然而在试验后,表示并没有解决问题ㄟ( ▔, ▔ )ㄏ。

# -*- coding: utf-8 -*- 
# coding = utf-8
方案二 IDE 设置编码格式

虽然在 「偏好设置 - Editor - File Encodings」 内全都设置(默认设置)了 UTF-8,但是在读入数据文件 ipdata.csv 的时候,还是出现了错误。我也很奇怪为什么没有生效。

方案三 修改默认 encoding 格式
  1. 在代码头部导入 sys 库;
  2. 重载 sys 库,网上说 Python 文件运行后,会删除 setdefaultencoding 方法?
  3. 设置默认 encoding 格式。
import sys
reload(sys) 
sys.setdefaultencoding('utf-8')

运行后显示找不到 setdefaultending 方法.

<img src="https://lh3.googleusercontent.com/-WkiXCB9eWCM/WnqrJSZdnTI/AAAAAAAAACg/eoGC0oY1UhgkWctNBjVyOtX1VCRWAzDgwCHMYCw/I/15179886333472.png" width = "140" alt="MySQL"/>

瞎捷豹愤而暴走,告诉我因为在 py3 中默认的编码格式为 unicode 解码?所以取消了 setdefaultending 方法。

正解:引入 codecs 库

codecs 库中的 open 方法可以添加 encoding 参数,完美解决。

import codecs

with open('./ipdata.csv', 'r', encoding='utf-8') as f:
    lines = f.readlines()

后来发现其实 3.6 版本的 py 早就集成了 open 函数的 encoding 参数。所以并不用导入 codecs 库。

批量写入

插入操作的 sql 写法为 :

insert into tablename (key1, key2, key3...) values (value1, value2, value3...)

使用 cursor.executemany() 方法来执行批量插入操作

方法为:

cursor = conn.cursor()
ret = cursor.executemany('insert into ipdata (id, startip, endip, country, carrier) values (%s, %s, %s, %s, %s)', nl_p_list)

失去连接报错

2055: Lost connection to MySQL server at '127.0.0.1:3306', system error: 32 Broken pipe

猜测是数据量太大所致,所以对读入的文件进行切片,分批插入表中;

    for i in range(int(len(nl_p_list)/1000 +1)):
        tmp_nl_p_list = nl_p_list[i*1000: (i+1)*1000]
        # 批量插入表中
        ret = cursor.executemany('insert into ipdata (id, startip, endip, country, carrier) values (%s, %s, %s, %s, %s)',
                       tmp_nl_p_list)

数据库插入中文错误

出现了新的报错,查看报错信息:

1366 (HY000): Incorrect string value: '\xE4\xBF\x9D\xE7\x95\x99...' for column 'carrier' at row 1

对报错信息显示 异常的 string 值,截取报错信息交给瞎捷豹,很快找到了解决方案;还是编码格式锅,不过这次是表结构编码格式不符。

在 navicat 表设计 - DDL 中查看 ipdata 的表结构:

CREATE TABLE `ipdata` (
  `id` int(11) NOT NULL,
  `startip` bigint(20) DEFAULT NULL,
  `endip` bigint(20) DEFAULT NULL,
  `country` text,
  `carrier` text,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

发现表编码为 latin1 。 果然不是 utf-8。通过 navicat 查询功能修改表编码格式,输入代码并执行:

alter table ipdata convert to character set utf8;

重新查看表结构:

CREATE TABLE `ipdata` (
  `id` int(11) NOT NULL,
  `startip` bigint(20) DEFAULT NULL,
  `endip` bigint(20) DEFAULT NULL,
  `country` text,
  `carrier` text,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

重新运行代码,数据成功写入表中。

<img src="https://lh3.googleusercontent.com/-gm4UYcEpZz8/Wnu-RGDEn2I/AAAAAAAAAEg/IyM3nyyt4iAZLW9ukAUJwoGe7LsRhpbcQCHMYCw/I/15180590714358.png" width = "600" alt="MySQL3"/>

使用 navicat 的查询功能: select count(*) from ipdata 得到记录行数 444963,写入记录正常。

计划通!


参考链接:
『mysql.connector 批量插入』:https://my.oschina.net/hhdys412/blog/182762

源码地址:
『NiuCodeLesson/insertSQL/』:https://github.com/wengfe/NiuCodeLesson/tree/master/insertSQL

博客地址:
『wengfe.win』:http://www.wengfe.win/2018/02/07/2018-02-07/#more

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,240评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,328评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,182评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,121评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,135评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,093评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,013评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,854评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,295评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,513评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,678评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,398评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,989评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,636评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,801评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,657评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,558评论 2 352

推荐阅读更多精彩内容