python-oracledb (new cx_Oracle) connection generating NotSupportedError DPY-3012 errors

Viewed 740

So I am trying the new oracledb python library, which replaces cx_oracle - as I dont want to have to install the oracle instant client.

un             = 'fred'
pwd            = 'mypass'
host           = 'server.mycompany.net'
port           =  1521
service_name   = 'servicea'


params = oracledb.ConnectParams(host=host, port=port, service_name=service_name)

with oracledb.connect(user=un, 
                      password=pwd,
                      params = params
                      ) as connection:
    
    with connection.cursor() as cursor:
        sql = "select * from dim_drug_product"
        for r in cursor.execute(sql):
            print(r)
 

And I just get this back:

File C:\ProgramData\Anaconda3\envs\ariel\lib\site-packages\oracledb\errors.py:103, in _raise_err(error_num, context_error_message, cause, **args) 101 message = f"{message}\n{context_error_message}" 102 exc_type = ERR_EXCEPTION_TYPES[error_num // 1000] --> 103 raise exc_type(_Error(message)) from cause

NotSupportedError: DPY-3012: national character set id 871 is not supported by python-oracledb in thin mode

2 Answers

The national character set 871 (UTF8, aka CESU-8) is not supported by the thin driver. You will have to either (a) use the thick driver instead or (b) switch to using the character set AL32UTF8, aka UTF-8. If you would like to request support for the older (non-standard) character set you can do so here: https://github.com/oracle/python-oracledb/issues.

To answer your query in the comment more fully: Oracle has character set names that differ from the standardized names that most of us are familiar with. Since Oracle was involved early on in the development of Unicode there are some confusing names!

  • Oracle name UTF8 corresponds to standard name CESU-8
  • Oracle name AL32UTF8 corresponds to standard name UTF-8

So yes, UTF8 and UTF-8 are different!

What's your database national character set?

SELECT value AS db_ncharset
FROM nls_database_parameters
WHERE parameter = 'NLS_NCHAR_CHARACTERSET';

There is a documented restriction in python-oracledb 1.0.0 about the 'national character set' (aka NCHAR) support: https://python-oracledb.readthedocs.io/en/latest/user_guide/globalization.html#character-sets-and-globalization

If your NCHAR character set isn't supported in Thin mode, then install Instant Client and use thick mode - or update your database to use a different NCHAR character set, or to use a base character set of AL32UTF8 and remove the use of NCHAR columns.

Related