因为数据库常常会有线上和线下的区分,有的时候会涉及到数据库的迁移,线上迁移到线下或者线下迁移到线上,最近有用到两种迁移方式,故在此作出总结。
方法一:用python脚本实现读写
思路:需要涉及到两个库的连接,从库A进行数据的读,然后往库B进行数据写入
脚本如下:
import pymysql
# 原始数据的数据连接
db1 = pymysql.connect(db='****', user='root', passwd='xxxx', host='127.0.0.1', port=3306,
charset='utf8')
cursor1 = db1.cursor()
# 定义每次读取的数量
sele_len = 10000
# 要读取的总数量
cursor_num = 17651480
for_time = int(cursor_num/sele_len)+1
for wan_nums in range(for_time):
print('第{}万数据,已经导出'.format(wan_nums))
len1 = cursor1.execute(
'select enterprise_name,rigister_code from company_task s where [s.id](http://s.id/) >{} and s.id<{}'.format(wan_nums * sele_len,
(wan_nums + 1) * sele_len))
# 迁移库的数据连接
db2 = pymysql.connect(db='****', user='****', passwd='*****', host='127.0.0.1', port=3308,
charset='utf8')
cursor2 = db2.cursor()
# 批量插入语句
sql = 'insert into table(task_id,enterprise_name,rigister_code) value(uuid(), %s, %s)'
# 每次循环导入的数据量
num = 1000
for i in range(int(len1 / num)):
print('第{}万数据中的{}千正在入库'.format(wan_nums,i))
data1 = cursor1.fetchmany(num)
try:
# try:
cursor2.executemany(sql, data1)
except Exception as e:
print(e)
print(data1)
continue
# 把剩下的数据一次性导入
data2 = cursor1.fetchall()
try:
cursor2.executemany(sql, data2)
except:
print(e)
print(data2)
continue
[db2.commit](http://db2.commit/)()
# 这种可以全部导入
# data2 = cursor1.fetchall()
# cursor2.executemany(sql, data2)
# 关闭数据库连接
db1.close()
db2.close()
该方法从线上读取速度很快但是往线上导入速度会巨慢,那有没有更好的方案呢?答案当然是有
方法二:通过第三方工具使用mysqldump来进行更快速的插入,这里我选择的工具是
datagrip
第一步导出:
点击之后不需要做额外的设置只需要将内容的output地址改为你想存放的地址
第二步导入:
到你需要导入的库中进行如下操作:
等就好啦,但是用这个工具的时候出现了插入报错:
ERROR 1273 (HY000) at line 25: Unknown collation: 'utf8mb4_0900_ai_ci'
仔细研究发现这个问题出现的原因是线上和线下的数据库版本不一致导致的
注:(以下摘自互联网,虽然不是很一致但是情况差不多)
MySQL 5.6 以及以上版本下,安装 WordPress 4.6 及以上版本的时候,默认的编码整理方式为 utf8mb4_unicode_520_ci,但是 MySQL 5.5 及以下版本的数据库,不支持 utf8mb4_unicode_520_ci,所以无法导入。
处理方式:
用sublime打开你所保存的sql文件:
command+f utf8mb4_0900_ai_ci
还真的有:
然后command shift f 将utf8mb4_0900_ai_ci 改为utf8mb4_unicode_ci进行替换并保存退出
进行替换并保存退出
整个过程会异常的慢,因为你的sql文件动辄几个g,慢慢等着
测试了一下ultra edit 比sublime要快好多,就和打开普通文件一样快,所以建议使用ultra edit
然后再重新导入就OK了!!!