一、大批量插入数据
对于 大量数据插入时,虽然pyDAL也手册中有个方法:bulk_insert(),但是手册也说了,虽然方法上是一次可以多条数据,如果后端数据库是关系型数据库,他转换为SQL时它是一条一条的插入的,只有在NoSQL数据库时能提速,bulk_insert()的用法如下,感兴趣的看看:
db.person.bulk_insert([{'name':'Alex','age':'11'}, {'name': 'John','age':'22'}, {'name': 'Tim','age':'33'}])
那后端是关系数据库时,有其他办法吗?答案是我们利用前面 我们提到:db.executesql()方法,直接用SQL,下面是例子,
1、目标:
MySQL数据库我们一次插入2000万的csv文件(普通PC是无法直接打开这么多行的数据文件的)
2、解决思路:
(1)分块读取,分块插入,我们已知csv各列的名为:col1,col2,col3,我们每次读10万行,插入库10万行);
(2)使用db.executesql()方法,编写SQL批量插入语句
(3)特别注意:将你的数据库的单条语句的数据包大小适当调大。就mysql而言:
# 服务器接受的数据包的大小,在执行数据量较大的单条语句,如果超过了默认限制,就会报错,提示这个参数大小不足
max_allowed_packet=100M
3、MySQL批量插入数据语法:
INSERT INTO table_name (column1, column2,...) VALUES ("value1_1", "value1_2",...), ("value2_1", "value2_2", ...)......;
4、示例代码:
我们使用到了pandas库,pandas的read_csv()方法可以对非常方便的对大文件分块读取:
import pandas as pd
df_chunk = pd.read_csv('my.csv', chunksize=100000, iterator=True)
for chunk in df_chunk:insert_values = ''for row in range(0, chunk.shape[0]):insert_values += '("' + str(chunk.iloc[row,0]) + '","' + str(chunk.iloc[row,1]) + '","' + str(chunk.iloc[row,2]) + '"),'db.executesql('INSERT INTO my_table (col1,col2,col3) VALUES ' + insert_values[:- 1] + ';')db.commit()
二、对于结果集很大的查询做遍历循环iterselect
如果我们要对一个查询结果集做遍历循环,且结果数据很大,例如:
for row in db(db.IMEI_table.IMEI.contains('666')).select():
.....
常规的上述写法,一定是先查询得到 完整的结果放在内存中,在做遍历循环,很吃内存,性能也低,针对这种情况,pyDAL提供了iterselect()方法,使用也很方便,如下:
for row in db(db.IMEI_table.IMEI.contains('666')).iterselect():
...
当数据量较大时,iterselect()不仅速度快,还节省内存: