使用 CLOB 和 BLOB 数据¶
神通 数据库使用 LOB 对象来存储文本、图像、视频和其他多媒体格式等大型数据。LOB 的最大大小限制为存储它的表空间的大小。 LOB 可以流式传输到 神通 数据库,也可以从 神通 数据库流式传输。 长度不超过 1 GB 的 LOB 也可以直接作为字符串或字节处理,STPython。这使得 LOB 易于使用,并且与流式处理相比具有显著的性能优势。但是,它要求整个LOB数据存在于Python内存中,这可能是不可能的。
LOB 绑定变量¶
例:
with open('example.txt', 'r') as f:
text_data = f.read()
with open('image.png', 'rb') as f:
img_data = f.read()
cursor.execute("insert into lob_tb (id, c, b) values (:id, :clobdata, :blobdata)",
id=1, clobdata=text_data, blobdata=img_data)
请注意,使用此方法时,LOB 数据的大小限制为 1 GB。
将 LOB 提取为字符串和字节¶
将数据量不大的CLOB 和 BLOB 可以直接从数据库中查询字符串和字节。这可能比流式传输快得多。
需要使用 Connection.outputtypehandler 或 Cursor.outputtypehandler,如以下示例所示:
cursor = connection.cursor()
createsql = """
CREATE TABLE lob_tb (
id NUMBER,
c CLOB,
b BLOB
);
"""
cursor.execute(createsql)
def output_type_handler(cursor, name, default_type, size, precision, scale):
if default_type == STPython.CLOB:
return cursor.var(STPython.STRING, arraysize=cursor.arraysize)
if default_type == STPython.BLOB:
return cursor.var(STPython.BINARY, arraysize=cursor.arraysize)
id = 1
clobData = "The quick brown fox jumps over the lazy dog"
blobData = b"Some binary data"
cursor.execute("insert into lob_tb (id, c, b) values (:1, :2, :3)",
[id, clobData, blobData])
connection.outputtypehandler = output_type_handler
cursor.execute("select c, b from lob_tb where id = :1", [id])
clob_data, blob_data = cursor.fetchone()
print("CLOB length:", len(clob_data))
print("CLOB data:", clob_data)
print("BLOB length:", len(blob_data))
print("BLOB data:", blob_data)
流式处理 LOB(读取)¶
如果没有输出类型处理程序,CLOB 和 BLOB 值将作为 LOB 对象提取。LOB 对象的大小可以通过调用 LOB.size() 获得,数据可以通过调用 LOB.read() 来读取。此方法的执行速度比一次性读取会更慢,因为它需要更多到 神通 数据库的往返行程,并且开销更高。但是,如果无法从服务器获取 LOB 数据作为一个数据块,则需要这样做。 若要对 BLOB 列进行流式处理,可以重复调用 LOB.read() 方法,直到读取完所有数据,如下所示:
cursor.execute("select b from lob_tb where id = :1", [10])
blob, = cursor.fetchone()
offset = 1
num_bytes_in_chunk = 65536
with open("image.png", "wb") as f:
while True:
data = blob.read(offset, num_bytes_in_chunk)
if data:
f.write(data)
if len(data) < num_bytes_in_chunk:
break
offset += len(data)
流式处理 LOB(写入)¶
如果要插入或更新包含 LOB 的行,并且要插入或更新的数据量无法放入单个数据块中,则可以使用方法 LOB.write() 对数据进行流式处理,如下面的代码所示:
createsql = """
CREATE TABLE lob_tb (
id NUMBER,
c CLOB,
b BLOB
);
"""
cursor.execute(createsql)
id_val = 1
lob_var = cursor.var(STPython.BLOB)
cursor.execute("""
insert into lob_tb (id, b)
values (:1, EMPTY_BLOB())
returning b into :2""", [id_val, lob_var])
lob = lob_var.getvalue()
offset = 1
num_bytes_in_chunk = 65536
with open("./FeiQ.exe", "rb") as f:
while True:
data = f.read(num_bytes_in_chunk)
if data:
lob.write(data, offset)
if len(data) < num_bytes_in_chunk:
break
offset += len(data)
connection.commit()