for row in handler.find(): parse_data(row) 短短4行代码,读取MongoDB里面的每一行数据,然后传入parse_data做处理。处理完成以后再读取下一行。逻辑清晰而简单,能有什么问题?只要parse_data(row)不报错,这一段代码就完美无缺。但事实并非这样。
你的代码可能会在for row in handler.find()这一行报错。它的原因,说来话长。要解释这个问题,我们首先就需要知道,handler.find()返回的并不是数据库里面的数据,而是一个游标(cursor)对象。
所以pymongo会一次性获取100行,for row in handler.find()循环第一次的时候,它会连上MongoDB,读取一百条数据,缓存到内存中。于是第2-100次循环,数据都是直接从内存里面获取,不会再连接数据库。 当循环进行到底101次的时候,再一次连接数据库,再读取第101-200行内容……,这个逻辑非常有效地降低了网络I/O耗时。但是,MongoDB默认游标的超时时间是10分钟。10分钟之内,必需再次连接MongoDB读取内容刷新游标时间,否则,就会导致游标超时报错:
pymongo.errors.CursorNotFound: cursor id 211526444773 not found