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

Howe to get ORDSYS.ORDIMAGE field value in python

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

问题是 cx_Oracle.OBJECT 没有 read() 方法。相反,它具有您可以 read/write 就像任何其他 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())