2015-04-23 17 views
0

我有一个有超过一百万行的CSV文件,我试图解析这个文件并将行插入数据库。Python CSV解析填满内存

with open(file, "rb") as csvfile: 

     re = csv.DictReader(csvfile) 
     for row in re: 
     //insert row['column_name'] into DB 

对于低于2 MB的csv文件,这种方法效果很好,但除此之外,最终还是吃掉了我的记忆。这可能是因为我将Dictreader的内容存储在名为“re”的列表中,并且无法遍历这么庞大的列表。我肯定需要访问带有列名的csv文件,这就是我选择dictreader的原因,因为它可以轻松地提供列级访问我的csv文件。任何人都可以告诉我为什么会发生这种情况,如何避免这种情况?

+1

http://stackoverflow.com/questions/24868856/reading-rows-of-big-csv-file-in-python – DhruvPathak

+1

虽然没有回答你的实际问题,但如果你需要加载数据,它可以使用DB自己的工具(例如,Postgres中的COPY表(col1,col2)FROM WITH CSV文件或MySQL中的LOAD DATA INFILE)可以更简单快捷地使用数据库。 –

回答

3

DictReader不加载整个文件在内存中,而是由作为this answer由DhruvPathak提出解释块阅读

但是,根据您的数据库引擎,磁盘上的实际写入只能在提交时发生。这意味着数据库(而不是csv阅读器)将所有数据保存在内存中,并最终耗尽它。

因此,您应该尝试提交每个n记录,其中n通常在10到1000之间,具体取决于您的行大小和可用内存。

+0

所以我想这是SQLAlchemy这是吃我的记忆 – Tania

+0

@Tania:只是试图提交每一个第n个声明,你会得到确认:-) –

+0

是的,我试过了。看起来这是我的问题。任何方法来避免它? – Tania

1

如果您不需要一次全部列,那么您可以像使用文本文件一样逐行读取文件并分析每一行。准确的分析取决于数据的格式,但你可以这样做:

delimiter = ',' 
with open(filename, 'r') as fil: 
    headers = fil.next() 
    headers = headers.strip().split(delimiter) 
    dic_headers = {hdr: headers.index(hdr) for hdr in headers} 
    for line in fil: 
     row = line.strip().split(delimiter) 
     ## do something with row[dic_headers['column_name']] 

这是一个很简单的例子,但它可以更精细。例如,如果您的数据包含,,则这不起作用。

+0

你可以告诉我,我以前的代码中的哪一行是一次取下所有的列? – Tania

+0

AFAIK csv阅读器内部已经遍历行并且不加载所有文件在内存中,所以我非常怀疑这真的解决了OP的问题 –

+0

我刚才看到并且连根拔起你的答案。我们每天都在学习。 –