在python中使用“HUGEBLOB”数据类型

2024-06-10 07:33:47 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个数据库,其中一列是BLOB数据类型(“STOREDFILEBLOB”)。使用TOAD(Oracle)查询数据库时,数据如下所示:

DOC    VERK    FILENAME       STOREDFILEBLOB
434    2343    sow2.rtf       (HUGEBLOB)
342    352     soodata.doc    (HUGEBLOB)
123    456     wan_tech.doc   (HUGEBLOB)

BLOB保存“FILENAME”列中引用的文档。我需要将BLOB以人类可读的形式摄取到python中;理想情况下,我希望它是一个长字符串,包含“FILENAME”文档的内容。我将使用BLOB中的信息做一些文本分类使用机器学习。我用下面的方法从数据库中读取。问题是,一旦将数据引入python,列就不再是BLOB,而是一个对象

conn = pyodbc.connect(conn_str)

query = '''
select dockey,verkey,filename,storedfileblob
from supportdoc 
where upper(filename) like '%SOO%' or upper(filename) like '%SOW%'
fetch first 15 rows only;
'''

test = pd.read_sql(query,conn)

print(test)
DOC    VERK    FILENAME          STOREDFILEBLOB
434    2343    sow2.rtf          b'\xa0\xa0\xa0\xa0\xfc\x0e\x00\x00\xff{\\rtf1\...
342    352     soo_data.doc      b'\xa0\xa0\xa0\xa0\xd3&\x00\x00\xff\xd0\xcf\x1...
123    456     wan_tech_sow.doc  b'\xa0\xa0\xa0\xa0\x8a\x19\x00\x00\xff\xd0\xcf...  


test.dtypes

DOC                float64
VERK               float64
FILENAME           object
STOREDFILEBLOB     object
dtype: object

我尝试使用以下sql在数据库中进行转换:

select DOC, VERK, FILENAME, UTL_RAW.CAST_TO_VARCHAR2(DBMS_LOB.substr(storedfileblob, 400,1))
from supportdoc 
where upper(filename) like '%SOO%' or upper(filename) like '%SOW%'

但我得到了这个荒谬的结果

DOC     VERK    FILENAME                            UTL_RAW.CAST_TO_VARCHAR2(DBMS_LOB.SUBSTR(
6908    8761    SOW (9503581Q0003).rtf          ü
9535    8890    Dataequip SOW9706000Q0008.doc       j
9553    8891    9602001Q0002WritingSOW.doc      T

方法2:

我决定退一步,先把.pdf文件解码成人类可读的格式。我将查询更新为只生成.pdf类型的文件,并且不使用pyodbc,而是使用cx\u Oracle,因为其他人都在使用它

新代码:

query = '''
select doc,verk,filename,storedfileblob
from supportdoc 
where (upper(filename) like '%SOO%' or upper(filename) like '%SOW%' or upper(filename) like '%PWS%')
and (substr(upper(filename),-3) like '%PDF%')
fetch first 15 rows only
'''

dsn = cx_Oracle.makedsn(host, port, sid)  
orcl = cx_Oracle.connect(username+'/'+password+'@'+dsn)
curs = orcl.cursor()
curs.execute(query)
rows = curs.fetchall()


for row in rows:
    filename = 'F:/Users/Acme'+'/contract_blob/'+str(row[0])+'_'+str(row[1])+'_dockey_verkey.pdf'
    f = codecs.open(filename, encoding='utf-16', mode='wb+')
    f.write(row[3].read())
    f.close()

上述代码产生:

TypeError: utf_16_encode() argument 1 must be str, not bytes

我随机选择了utf-16作为编码。我做了一些研究,PDF往往是utf-16(至少这是我从阅读中了解到的)。我只是在抓救命稻草

归根结底,我的目标是一样的。我需要从数据库中检索BLOB,然后解码BLOB并获得可读的文档。我从pdf文档开始。还有.doc、.png。和.zip类型的BLOB文件。我希望一旦我完善了.pdfs的方法,就可以更容易地处理.doc BLOBs。我可能会忽略.png和.zip文件。感谢您的帮助


Tags: 文档数据库docfilenameupperbloblikeoracle