如何使用 Pandas 将巨大的 CSV 转换为 SQLite?
How to transform a huge CSV into SQLite using Pandas?
我有一个很大的 table(大约 60 GB)的存档 CSV 文件。我想将它转换成一个 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 将整个 table 读入内存 (RAM),然后将其保存到 SQLite 文件中。
这个问题有没有优雅的解决方案?
由于其大小,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)
我还没有用那种大小的 CSV 做过任何工作,但听起来这种事情 Odo 可能会很快解决。
我粗略地检查了文档,他们似乎已经 written something 解决了 larger-than-memory CSV 解析到 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
[更新于 2017 年 6 月 15 日]
似乎 csv2sqlite.py 可能是使用 SQLite 的方法。毫无疑问,Chuck-by-Chuck 对于大文件(> 1GB)来说太慢了。当我用 csv2sqlite.py 测试一个 6.5GB 的 nyc311calls.csv 时,只用了大约 24 分钟就创建了一个数据类型猜测的 SQLite 数据库文件。 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)将大table的一小部分导入到pandas。
2)处理并将它们加载到SQLite。
3) 继续这个过程。
我上传了我所做的更详细的过程here (Jupyter file) if you are interested in. You can find the NYC311call data here
我的一些评论。
1) 如果您的数据包含空字符串,Odo 包将无法正常工作。我希望他们能改善这些问题。也就是说,如果您的数据非常干净且组织良好,Odo 包可能是您的选择。
2) 上述方法是一项非常耗时的工作。特别是,一个 ~6GB 的 table 需要超过 24 小时。因为 pandas 很慢。
3) 如果你不坚持使用 SQLite,我会说 MySQL 和 "LOAD DATA INFILE" 对你来说是个不错的选择。您可以从互联网搜索中找到如何使用它。只要我测试过,这是非常可靠和有效的方式。如果你真的需要使用 sqlite,你可以转换到 sqlite。特别是,如果数据有很多空字符串和 datetime 列,需要转换为 datetime 类型,我肯定会选择 MySQL。
我有一个很大的 table(大约 60 GB)的存档 CSV 文件。我想将它转换成一个 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 将整个 table 读入内存 (RAM),然后将其保存到 SQLite 文件中。
这个问题有没有优雅的解决方案?
由于其大小,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)
我还没有用那种大小的 CSV 做过任何工作,但听起来这种事情 Odo 可能会很快解决。
我粗略地检查了文档,他们似乎已经 written something 解决了 larger-than-memory CSV 解析到 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
[更新于 2017 年 6 月 15 日]
似乎 csv2sqlite.py 可能是使用 SQLite 的方法。毫无疑问,Chuck-by-Chuck 对于大文件(> 1GB)来说太慢了。当我用 csv2sqlite.py 测试一个 6.5GB 的 nyc311calls.csv 时,只用了大约 24 分钟就创建了一个数据类型猜测的 SQLite 数据库文件。 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)将大table的一小部分导入到pandas。 2)处理并将它们加载到SQLite。 3) 继续这个过程。
我上传了我所做的更详细的过程here (Jupyter file) if you are interested in. You can find the NYC311call data here
我的一些评论。
1) 如果您的数据包含空字符串,Odo 包将无法正常工作。我希望他们能改善这些问题。也就是说,如果您的数据非常干净且组织良好,Odo 包可能是您的选择。
2) 上述方法是一项非常耗时的工作。特别是,一个 ~6GB 的 table 需要超过 24 小时。因为 pandas 很慢。
3) 如果你不坚持使用 SQLite,我会说 MySQL 和 "LOAD DATA INFILE" 对你来说是个不错的选择。您可以从互联网搜索中找到如何使用它。只要我测试过,这是非常可靠和有效的方式。如果你真的需要使用 sqlite,你可以转换到 sqlite。特别是,如果数据有很多空字符串和 datetime 列,需要转换为 datetime 类型,我肯定会选择 MySQL。