Chr*_*rth 6 python oracle cx-oracle blob lob
我正在开发一个系统的一部分,其中进程限制在大约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())
Run Code Online (Sandbox Code Playgroud)
lob.read()
MemoryError
当我们点击一个大于300-350MB的文件时,显然会失败,所以我们尝试过这样的东西,而不是一次性读取所有内容:
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)
Run Code Online (Sandbox Code Playgroud)
不幸的是,我们仍然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])
Run Code Online (Sandbox Code Playgroud)
这一次拉出2000个字节(argh),并且需要永久(对于1.5GB文件,这需要两个小时).为什么2000字节?根据Oracle文档,dbms_lob.substr()
将其返回值存储在RAW中,该RAW限制为2000字节.
有没有什么方法可以将dbms_lob.substr()
结果存储在一个更大的数据对象中,一次读取几兆字节?我如何使用cx_Oracle执行此操作?
归档时间: |
|
查看次数: |
1998 次 |
最近记录: |