gpt4 book ai didi

python - 如何在内存受限的系统上使用 cx_Oracle 下载巨大的 Oracle LOB?

转载 作者:太空狗 更新时间:2023-10-30 00:17:58 24 4
gpt4 key购买 nike

我正在开发一个系统的一部分,其中的进程被限制为大约 350MB 的 RAM;我们使用cx_Oracle从外部系统下载文件进行处理。

外部系统将文件存储为 BLOB,我们可以像这样获取它们:

# ... set up Oracle connection, then
cursor.execute(u"""SELECT filename, data, filesize
FROM FILEDATA
WHERE ID = :id""", id=the_one_you_wanted)
filename, lob, filesize = cursor.fetchone()

with open(filename, "w") as the_file:
the_file.write(lob.read())
当我们访问一个大于 300-350MB 的文件时,

lob.read() 显然会因 MemoryError 而失败,因此我们尝试了类似的方法而不是读取它一次全部:

read_size = 0
chunk_size = lob.getchunksize() * 100
while read_size < filesize:
data = lob.read(chunk_size, read_size + 1)
read_size += len(data)
the_file.write(data)

不幸的是,在多次迭代后我们仍然得到MemoryError。从 lob.read() 开始,以及我们最终得到的内存不足情况,看起来好像 lob.read() 正在拉取( chunk_size + read_size ) 字节从数据库每次。也就是说,读取需要 O(n) 的时间和 O(n) 的内存,即使缓冲区要小得多。

为了解决这个问题,我们尝试了类似的方法:

read_size = 0
while read_size < filesize:
q = u'''SELECT dbms_lob.substr(data, 2000, %s)
FROM FILEDATA WHERE ID = :id''' % (read_bytes + 1)
cursor.execute(q, id=filedataid[0])
row = cursor.fetchone()
read_bytes += len(row[0])
the_file.write(row[0])

这一次拉取 2000 字节 (argh),并且需要很长时间(对于 1.5GB 的文件大约需要两个小时)。为什么是 2000 字节?根据 Oracle 文档,dbms_lob.substr() 将其返回值存储在 RAW 中,限制为 2000 字节。

有什么方法可以将 dbms_lob.substr() 结果存储在一个更大的数据对象中,一次读取可能只有几兆字节?我如何使用 cx_Oracle 执行此操作?

最佳答案

我认为 lob.read() 中的参数顺序在您的代码中颠倒了。第一个参数应该是偏移量,第二个参数应该是读取的数量。这将解释 O(n) 时间和内存使用情况。

关于python - 如何在内存受限的系统上使用 cx_Oracle 下载巨大的 Oracle LOB?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12674806/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com