比 HDF5 更好的方法 -> Pandas -> PostgreSQL

Better way than HDF5 -> Pandas -> PostgreSQL

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

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

基本上从 HDF5 -> Pandas -> PostgreSQL,将需要通过大量的猴子修补来克服障碍 1 和 2。而且似乎没有直接从 HDF5 -> PostgreSQL 直接去的方法。除非我遗漏了什么。

也许你们中的一位好用户可以提示我遗漏的东西,你创建的一些拼凑来克服类似的问题,这将有助于我的事业,或者任何建议或建议...

您可以使用类似以下内容转换为 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()