-
Notifications
You must be signed in to change notification settings - Fork 93
Description
cx_Oracle and oracledb have different behavior when setting undecodable bytes data to an object type.
obj = mytype.newobject()
obj.DATA = b'\x1f\x8b\x08\x00\xa7'
In cx_Oracle, this will not raise an error, and will save the bytes to Oracle correctly.
In oracledb, this raises a UnicodeDecodeError
My use case is that I am logging http requests to an Oracle table. Some requests contain Excel uploads. The bytes for an Excel file are not decodable into the str type.
I have a package with a record type, collection of that record, and a procedure to save the http logs in bulk.
Setting an attribute on the record type to the Excel bytes works on cx_Oracle, and saves to the database correctly.
In oracledb, it doesn't work.
Here is a minimum reproducable example.
CREATE PACKAGE MYPACKAGE
IS
TYPE MY_RECORD_TYPE IS RECORD (
data VARCHAR2(4000)
);
END MYPACKAGE;
import cx_Oracle
import oracledb
oracledb.init_oracle_client()
# These bytes can be found in the start of any Excel and cannot be decoded to str
bad_bytes = b'\x1f\x8b\x08\x00\xa7'
ORACLE_DSN = 'scott/tiger@local'
PLSQL_RECORD_TYPE = 'MYSCHEMA.MYPACKAGE.MY_RECORD_TYPE'
# It works fine with cx_Oracle
cx_conn = cx_Oracle.connect(ORACLE_DSN)
cx_type = cx_conn.gettype(PLSQL_RECORD_TYPE)
cx_rec = cx_type.newobject()
# This works
cx_rec.DATA = bad_bytes
# It fails with oracledb in thick mode
od_conn = oracledb.connect(ORACLE_DSN)
od_type = od_conn.gettype(PLSQL_RECORD_TYPE)
od_rec = od_type.newobject()
od_rec.DATA = bad_bytes
-
What versions are you using?
oracledb.version
'1.2.1'
Give your database version.
19c
Also run Python and show the output of:
>>> print("platform.platform:", platform.platform())
platform.platform: Linux-5.10.102.1-microsoft-standard-WSL2-x86_64-with-glibc2.28
>>> print("sys.maxsize > 2**32:", sys.maxsize > 2**32)
sys.maxsize > 2**32: True
>>> print("platform.python_version:", platform.python_version())
platform.python_version: 3.10.9
>>> oracledb.__version__
'1.2.1'
- Is it an error or a hang or a crash?
Error
- What error(s) or behavior you are seeing?
>>> orr.REQUEST_DATA = bad_bytes
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/app/project/lib/python3.10/site-packages/oracledb/dbobject.py", line 54, in __setattr__
self._impl.set_attr_value(attr_impl, value)
File "src/oracledb/impl/base/dbobject.pyx", line 94, in oracledb.base_impl.BaseDbObjectImpl.set_attr_value
File "src/oracledb/impl/base/connection.pyx", line 76, in oracledb.base_impl.BaseConnImpl._check_value
UnicodeDecodeError: 'utf-8' codec can't decode byte 0x8b in position 1: invalid start byte
- Does your application call init_oracle_client()?
Yes, thick mode.
- Include a runnable Python script that shows the problem.
See above.
Include all SQL needed to create the database schema.
Format code by using three backticks on a line before and after code snippets, for example: