BLOB / CLOB read & write
informix-driver reads and writes smart-LOB columns (BLOB and CLOB) end-to-end without any native machinery. The implementation uses Informix’s lotofile and filetoblob SQL functions, intercepted at the SQ_FILE (98) wire-protocol level.
Reading a BLOB
Section titled “Reading a BLOB”data: bytes = cur.read_blob_column( "SELECT data FROM photos WHERE id = ?", (42,),)read_blob_column returns the raw bytes. For very large BLOBs (multi-GB), see the streaming variant below.
Writing a BLOB
Section titled “Writing a BLOB”cur.write_blob_column( "INSERT INTO photos VALUES (?, BLOB_PLACEHOLDER)", blob_data=jpeg_bytes, params=(42,),)The BLOB_PLACEHOLDER token in the SQL marks where the BLOB data goes. Other parameters are bound positionally to params=.
Reading a CLOB
Section titled “Reading a CLOB”CLOBs use the same methods as BLOBs, and there is no separate read_clob_column. read_blob_column returns bytes for both, so decode it with the encoding the column was written in:
raw: bytes = cur.read_blob_column( "SELECT body FROM articles WHERE id = ?", (42,),)text: str = raw.decode("iso-8859-1") # or your DB_LOCALE's codecReturning bytes rather than str is deliberate: the driver transports the LOB over the SQ_FILE channel and never sees the column’s declared character set, so guessing an encoding here would be exactly the kind of silent assumption that produces mojibake in one deployment and works fine in another.
Writing a CLOB
Section titled “Writing a CLOB”Pass clob=True so the write routes through filetoclob rather than filetoblob, and encode the text yourself:
cur.write_blob_column( "INSERT INTO articles VALUES (?, BLOB_PLACEHOLDER)", "long article text… café résumé".encode("iso-8859-1"), (42,), clob=True,)The placeholder token is BLOB_PLACEHOLDER for both BLOB and CLOB writes.
Server-side prerequisites
Section titled “Server-side prerequisites”How it works (briefly)
Section titled “How it works (briefly)”The lotofile server function returns a smart-LOB descriptor as a regular result column when called via SELECT. The driver intercepts the SQ_FILE (PDU 98) response that contains the LOB bytes and reassembles them client-side.
Writing reverses the flow: filetoblob is invoked via a placeholder pattern in the SQL, the driver sends the bytes via SQ_FILE PDUs, and the server stores them in the sbspace.
The architectural pivot from the heavier SQ_FPROUTINE + SQ_LODATA stack to this lighter SQ_FILE intercept is documented in Phase 10/11 of the decision log. The result is roughly 3× smaller than originally projected.