【问题标题】:Better way than HDF5 -> Pandas -> PostgreSQL比 HDF5 -> Pandas -> PostgreSQL 更好的方法
【发布时间】:2016-12-23 11:39:41
【问题描述】:

我有 51 个大型 HDF5 表,每个表都有足够的(行为良好的)数据,我什至无法将其中一个完全加载到内存中。为了让我的团队其他成员的生活更轻松,我需要将这些数据传输到 PostgreSQL 数据库中(并删除 HDF5 表)。然而,这说起来容易做起来难,主要是因为这些障碍:

  1. pandas.read_hdf() 仍然有一个不稳定的chunksize kwag:SO Question; Open github issue
  2. pandas.DataFrame.to_sql() 非常缓慢且效率低下:Open github issue(请参阅问题页面底部的我的帖子)
  3. PostgreSQL 没有本地或第三方数据包装器来处理 HDF5:PostgreSQL wiki article
  4. HDF5 ODBC 驱动程序仍处于初期阶段:HDF5 ODBC blog

基本上从 HDF5 -> Pandas -> PostgreSQL 开始,需要通过大量的猴子补丁来克服障碍 1 和 2。而且似乎没有直接的方法可以直接从 HDF5 -> PostgreSQL 出发。除非我错过了什么。

也许你们中的一个优秀用户可以暗示我缺少的东西,你创建的一些拼凑以克服有助于我的事业的类似问题,或者任何建议或建议......

【问题讨论】:

  • 请问您想从 HDF5 迁移到 PostgreSQL 的原因是否是 HDF5 不支持 PostgreSQL 支持的复杂查询?根据我的经验,HDF5 在简单查询(例如,查询时间序列数据的时间范围的数据)方面比 PostgreSQL 快得多。
  • 没有。 PostgreSQL 是我当时工作的公司的存储平台。他们有围绕从 PostgreSQL 读取而构建的工具,并且不想重新调整他们的流程。我使用 HDF5 的唯一原因是速度。但我需要将数据传输到 PostgreSQL。

标签: postgresql pandas hdf5 large-data


【解决方案1】:

您可以使用以下内容转换为 CSV:

import csv
import h5py
with h5py.File('input.hdf5') as hdf5file:
    with open('output.csv', 'w') as csvfile:
        writer = csv.writer(csvfile)
        for row in hdf5file['__data__']['table']:
            writer.writerow(row)

然后用psql导入postgres:

create table mytable (col1 bigint, col2 float, col3 float);
\copy mytable from 'output.csv' CSV

根据数据的复杂性,您可能会做一些聪明的事情来从 hdf5 文件中获取架构并使用它来制作 CREATE TABLE 语句。

或者,您可以尝试在 Python 脚本中编写自己的 INSERT 语句,这可能会比使用 COPY 慢,但可能是一个更简单的解决方案:

import psycopg2
from itertools import islice

with h5py.File('input.hdf5') as hdf5file:
    with psycopg2.connect("dbname=mydb user=postgres") as conn
        cur = conn.cursor()
        chunksize=50
        t = iter(hdf5file['__data__']['table'])
        rows = islice(t, chunksize)
        while rows != []:
            statement = "INSERT INTO mytable VALUES {}".format(','.join(rows))
            cur.execute(row)
            rows = islice(t, chunksize)
        conn.commit()

【讨论】:

  • 这是我没有考虑过的替代方案。感谢您指出这一点。但是,在大约 11M 行和 200 列的 hdf 文件上,您不认为循环复制会花费大量时间吗?我可以轻松获取文件架构并创建 create table 语句。此外,所有文件都具有相同的结构,因此只需要完成一次(如果迫不得已,我可以手动完成)。尽管如此,让我不接受这个答案的还是逐行写...
  • 试一试,我认为写入应该非常快,并且像这样循环遍历 hdf5 表将使用迭代器,因此不会占用内存。
  • 刚刚进行了测试,在我的笔记本电脑上将 200 个浮点列写入 csv 大约是 3000 行/秒
  • 我会的。对一系列文件进行测试。谢谢。
  • 我已经编辑了我的答案以对插入进行分组,但它仍然比使用 \copy 慢得多
猜你喜欢
  • 1970-01-01
  • 2017-09-01
  • 2014-06-03
  • 2017-06-26
  • 1970-01-01
  • 2012-11-30
  • 2020-11-09
  • 2018-02-10
  • 1970-01-01
相关资源
最近更新 更多