一种将数据从非常大的 csv 写入 SQL 数据库的方法

Posted

技术标签:

【中文标题】一种将数据从非常大的 csv 写入 SQL 数据库的方法【英文标题】:A way to write data from very large csv into SQL database 【发布时间】:2016-10-28 14:24:02 【问题描述】:

我有多个 csv 文件,内容如下:

Duration (ms),Start date,End date,Start station number,Start station,End station number,End station,Bike number,Member Type
840866,8/31/2016 23:59,9/1/2016 0:13,31117,15th & Euclid St  NW,31228,8th & H St NW,W20409,Registered

我有大约 1000 万个原始数据。

我需要规范化这些数据并将其拆分为表格。我想会有桌子:车站,自行车,游乐设施。就 OLAP 而言,骑行是事实,车站和自行车是维度。我对数据分析很陌生,所以我可能会使用不正确的术语。但我正在尝试使用this 方法。

所以问题是如何将这些数据尽可能优化地写入数据库?我能想象的方法如下:

1) Read line from csv
2) Create a record for station and get foreign key for it (with direct SQL query).
3) Create a record for a bike and get FK for it.
4) Create a record for a datetime (i'm not sure if it could be useful for further data analysis)
5) Create a record for ride with FK for each of it 'dimensions'
6) Repeat

但如果我有 1000 万行,这种方法将对数据库进行约 4000 万次查询,这看起来很糟糕而且不是最优的。

是否有更优化的方法/算法/技术来做到这一点?如果它很重要,我将使用 python 和 psql。

【问题讨论】:

1) 使用copy 命令(docs for PG 和docs for psycopg)将整个数据加载到临时表中; 2) 使用 SQL 拆分数据 根据您的 Postgresql 版本,您可以使用 file_fdw 并直接选择 csv 文件(无需预加载)。 【参考方案1】:

您可以节省memoizing the function 创建唯一记录的查询,例如:

from functools import lru_cache

@lru_cache(maxsize=128)
def save_station(s):
    """Create station record and return primary key."""
    station = create_or_get_station_record(...)
    return station.id

如果输入是按站排序的,那么一旦创建记录,随后对save_station 的调用将不会查询数据库。即使它没有完美排序,这也会有所帮助。

您可以批量保存游乐设施。累积记录,然后调用execute_many 函数(取决于您使用的库)。

您可以预处理数据以创建单独的 CSV 文件,然后加载每个文件。

【讨论】:

【参考方案2】:

根据PostgreSQL documentation,copy 命令是填充具有大量行的表的最佳方法。另一方面,对于处理 csv 文件,pandas library 是最好的工具之一。

所以下面的步骤可能是一个可以接受的解决方案:

Load csv files into data-frames with pandas read_csv()
Process the data-frames into the desired form
Store processed data-frames into temporary csv files
Create desired tables using SQL
Load data from temporary csv files into tables using copy SQL command

【讨论】:

以上是关于一种将数据从非常大的 csv 写入 SQL 数据库的方法的主要内容,如果未能解决你的问题,请参考以下文章

使用 Python 或 R 将非常大的 sql 文件导出到 csv

如何在 Spark 中写入 CSV

AWS Glue - 从 sql server 表中读取并作为自定义 CSV 文件写入 S3

使用 Python 将 Csv 文件写入 SQL Server 数据库中已有的表

用 Python 编写 HDF5 文件的最快方法?

解析一个非常大的 CSV 数据集