将cx_Oracle 5.2.1与Oracle客户端库11.2和Oracle服务器11.2一起使用,我无法检索ORDSYS.ORDIMAGE
字段的内容。
以下代码引发attribute read not found exception
:
import cx_Oracle
db = cx_Oracle.Connection('user/pass@ip/t')
cursor = db.cursor()
cursor.execute("select IMAGE from T where ROWID in ('AAAAAAAAAA')")
bf, = cursor.fetchone()
bfile_data = bf.read()
引发的例外是:AttributeError: 'cx_Oracle.OBJECT' object has no attribute 'read'
答案 0 :(得分:1)
问题是cx_Oracle.OBJECT没有read()方法。相反,它具有可以像任何其他Python对象一样读/写的属性。
使用未发布的cx_Oracle版本,以下通用代码将起作用:
def ObjectRepr(obj):
if obj.type.iscollection:
returnValue = []
for value in obj.aslist():
if isinstance(value, cx_Oracle.Object):
value = ObjectRepr(value)
returnValue.append(value)
else:
returnValue = {}
for attr in obj.type.attributes:
value = getattr(obj, attr.name)
if value is None:
continue
elif isinstance(value, cx_Oracle.Object):
value = ObjectRepr(value)
returnValue[attr.name] = value
return returnValue
print(ObjectRepr(bf))
但是,如果您使用的是5.2.1,那么一些内省代码将无法使用。幸运的是,你不需要那样做。您可以在SQL * Plus中描述类型,它将在输出开头显示属性列表
desc ordsys.ordimage
这应该允许您在Python代码中执行以下操作:
print(bf.HEIGHT)
print(bf.WIDTH)
print(bf.CONTENTLENGTH)
print(bf.FILEFORMAT)
请注意,属性SOURCE是另一个对象,因此您可以以相同的方式访问其属性:
print(bf.SOURCE.SRCNAME)
print(bf.SOURCE.UPDATETIME)
等等。
属性bf.SOURCE.LOCALDATA的类型为BLOB,目前不受支持。您可以使用匿名PL / SQL块来访问其值:
var = cursor.var(cx_Oracle.BLOB)
cursor.execute("""
declare
t_Image ordsys.ordimage;
begin
select Image
into t_Image
from T
where rownum <= 1;
:1 := t_Image.source.localdata;
end;""", (var,))
blob = var.getvalue()
print("Image data is:", blob.read())