首页 文章

从Oracle读取包含数百万行的大表并写入HDF5

提问于
浏览
11

我正在使用具有数百万行和100列的Oracle数据库 . 我试图使用带有索引的某些列的pytables将这些数据存储在HDF5文件中 . 我将在pandas DataFrame中读取这些数据的子集并执行计算 .

我尝试过以下方法:

下载表,使用实用程序到csv文件中,使用pandas通过chunk读取csv文件块,并使用 pandas.HDFStore 附加到HDF5表 . 我创建了一个dtype定义并提供了最大的字符串大小 .

但是,现在当我尝试直接从Oracle DB下载数据并通过 pandas.HDFStore 将其发布到HDF5文件时,我遇到了一些问题 .

pandas.io.sql.read_frame不支持分块读取 . 我没有足够的RAM能够先将整个数据下载到内存中 .

如果我尝试使用具有固定数量记录的 cursor.fecthmany() ,则在DB表中读取操作需要很长时间才能编入索引,并且我必须读取属于日期范围的记录 . 我正在使用 DataFrame(cursor.fetchmany(), columns = ['a','b','c'], dtype=my_dtype) 但是,创建的DataFrame总是推断dtype而不是强制执行我提供的dtype(与read_csv不同,它遵循我提供的dtype) . 因此,当我将此DataFrame附加到已存在的 HDFDatastore 时,存在类型不匹配的情况,例如float64可能会在一个块中解释为int64 .

如果你们能提出你的想法并指出我正确的方向,那就表示赞赏 .

2 回答

  • 1

    嗯,现在唯一实用的解决方案就是直接使用PyTables,因为它是专为内存不足而设计的...这有点乏味但不是那么糟糕:

    http://www.pytables.org/moin/HintsForSQLUsers#Insertingdata

    另一种使用Pandas的方法是:

    "Large data" work flows using pandas

  • 0

    好的,所以我对oracle数据库没有多少经验,但是这里有一些想法:

    您对来自oracle的任何特定记录的访问时间都很慢,因为缺少索引,并且您希望数据按时间戳顺序排列 .

    首先,您无法为数据库启用索引?

    如果您无法操作数据库,您可以假设请求一个只包含每行的有序唯一ID的搜索结果集?

    您可以将此数据存储为单个唯一ID数组,并且您应该能够适应内存 . 如果你为每个唯一密钥允许4k(保守估计,包括开销等),并且你没有保留时间戳,所以它只是一个整数数组,它可能会耗费大约1.1GB的RAM用于300万条记录 . 这不是一堆,可能你只想要一个活动数据的小窗口,或者你可能正在逐行处理?

    使生成器功能完成所有这些 . 这样,一旦你完成迭代,它应该释放内存,而不必去任何东西,它也使你的代码更容易遵循,并避免膨胀你的计算循环的实际重要逻辑 .

    如果你不能将它全部存储在内存中,或者由于某些其他原因这不起作用,那么你能做的最好的事情就是计算出你可以存储多少内存 . 您可以将作业分成多个请求,并在最后一个请求完成后使用多线程发送请求,同时将数据处理到新文件中 . 在您要求返回数据之前,它不应该耗尽内存 . 如果延迟是满足请求或正在下载的数据,请尝试并确定 .

    从它的声音来看,你可能会抽象数据库,让pandas发出请求 . 值得看看它如何限制结果 . 您应该能够对所有数据发出请求,但只能从数据库服务器一次加载一行结果 .

相关问题