我有一个存档的CSV文件形式的大表(大约60 GB)。我想将其转换为SQLite文件。
目前我在做什么:
import pandas
import sqlite3
cnx = sqlite3.connect('db.sqlite')
df = pandas.read_csv('db.gz', compression='gzip')
df.to_sql('table_name', cnx)
它适用于较小的文件,但有大文件我有内存问题。问题是pandas将整个表读入内存(RAM),然后将其保存到SQLite文件中。
这个问题有一个优雅的解决方案吗?
答案 0 :(得分:6)
我还没有使用那么大的CSV进行任何工作,但这听起来像Odo可能会很快解决的事情。
我粗略检查了文档,看起来他们已经written something解决了大于内存的CSV解析到SQL数据库的问题,这些SQL数据库专门将SQLite3作为目标调用。
这是他们发布用于解析33 GB文本文件的示例。
In [1]: dshape = discover(resource('all.csv'))
In [2]: %time t = odo('all.no.header.csv', 'sqlite:///db.db::nyc',
...: dshape=dshape)
CPU times: user 3.09 s, sys: 819 ms, total: 3.91 s
Wall time: 57min 31s
答案 1 :(得分:4)
pandas
因大小问题而出现问题。您无法使用csv
模块并迭代文件的任何原因。
基本理念(未经测试):
import gzip
import csv
import sqlite3
with gzip.open('db.gz') as f, sqlite3.connect('db.sqlite') as cnx:
reader = csv.reader(f)
c = cnx.cursor()
c.executemany('insert into table_name values (?,?,...)', reader)
答案 2 :(得分:2)
[更新于06-15-2017]
似乎csv2sqlite.py可能是SQLite的常规方式。绝对是,Chuck-by-Chuck对于大文件来说太慢了(> 1GB)。当我使用csv2sqlite.py测试6.5GB的nyc311calls.csv时,创建一个数据类型为猜测的SQLite数据库文件只需要大约24分钟。 24分钟类似于MySQL使用" LOAD DATA INFILE"的消费时间。即使您可能需要更改某些列的数据类型,这也不错。在我看来,使用csv2sqlite.py是目前从csv文件创建SQLite数据库文件最省时的方法。
1)从here下载csv2sqlite.py并将其放在包含csv文件的目录中。
2)使用Windows Prompt
,转到包含要导入的csv2sqlite.py和csv文件(例如nyc311calls.csv)的目录。
3)运行python csv2sqlite.py nyc311calls.csv database_name.db
的代码并等待。注意:python PATH应包含在Windows Environment Variables
。
这是一个有点旧的任务,但似乎没有人给出明确的答案。 我希望我的回答能帮到你。使用Sqlite,我建议您查看this site,它可以提供您的想法以及您应该做什么,一块一块的负载。我测试了几种方法,但到目前为止,这是我认为最可靠的方法。
基本程序是这样的: 1)将大表的一小部分导入熊猫。 2)处理并加载到SQLite。 3)继续这个过程。
如果您感兴趣,我上传了我所做的更详细的程序here(Jupyter文件)。您可以找到NYC311call数据here
我的一些评论。
1)如果数据包含空字符串,则Odo包不能完全正常工作。我希望他们可以改善这些问题。即如果您的数据非常干净且组织良好,则可以选择使用Odo包。
2)上述方法是一项非常耗时的工作。特别是,约6GB的表需要超过24小时。因为大熊猫很慢。
3)如果你不坚持使用SQLite,我会说MySQL带有" LOAD DATA INFILE"对你来说是个不错的选择。您可以通过互联网搜索找到如何处理它。只要我测试过,这是一种非常可靠和有效的方法。如果你真的需要使用sqlite,你可以转换为sqlite。特别是,如果数据有许多空字符串和日期时间列,这些列是转换为datetime类型所必需的,我肯定会使用MySQL。