在python

时间:2019-11-13 22:36:13

标签: python sql oracle

我有一个数据库,其中的一列是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保存“文件名”列中引用的文档。我需要将人类可读形式的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_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文件。我希望一旦我完善了.pdf的方法,便可以更轻松地处理.doc BLOB。我可能会忽略.png和.zip文件。任何帮助表示赞赏。

0 个答案:

没有答案