你如何在python中获取ORDSYS.ORDIMAGE字段值

时间:2016-10-18 07:34:03

标签: python oracle cx-oracle

将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'

1 个答案:

答案 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

这应该允许您在Py​​thon代码中执行以下操作:

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())