diff options
| author | Mike Bayer <mike_mp@zzzcomputing.com> | 2022-10-31 15:09:34 -0400 |
|---|---|---|
| committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2022-11-01 17:05:52 -0400 |
| commit | 32b2b31da2017fae8fcb759a52ad3d7081dec933 (patch) | |
| tree | 7ddcf1583f8bf34e0d1d441f20240f1193629966 /lib/sqlalchemy/dialects | |
| parent | 66f3533de86506327c753c1ea80b121692535745 (diff) | |
| download | sqlalchemy-32b2b31da2017fae8fcb759a52ad3d7081dec933.tar.gz | |
use simple decimal query to detect decimal char
Fixed issue where the ``nls_session_parameters`` view queried on first
connect in order to get the default decimal point character may not be
available depending on Oracle connection modes, and would therefore raise
an error. The approach to detecting decimal char has been simplified to
test a decimal value directly, instead of reading system views, which
works on any backend / driver.
Fixes: #8744
Change-Id: I39825131c13513798863197d0c180dd5a18b32dc
Diffstat (limited to 'lib/sqlalchemy/dialects')
| -rw-r--r-- | lib/sqlalchemy/dialects/oracle/cx_oracle.py | 31 |
1 files changed, 27 insertions, 4 deletions
diff --git a/lib/sqlalchemy/dialects/oracle/cx_oracle.py b/lib/sqlalchemy/dialects/oracle/cx_oracle.py index 24262c181..5a0c0e160 100644 --- a/lib/sqlalchemy/dialects/oracle/cx_oracle.py +++ b/lib/sqlalchemy/dialects/oracle/cx_oracle.py @@ -1133,10 +1133,33 @@ class OracleDialect_cx_oracle(OracleDialect): # NLS_TERRITORY or formatting behavior of the DB, we opt # to just look at it - self._decimal_char = connection.exec_driver_sql( - "select value from nls_session_parameters " - "where parameter = 'NLS_NUMERIC_CHARACTERS'" - ).scalar()[0] + dbapi_connection = connection.connection + + with dbapi_connection.cursor() as cursor: + # issue #8744 + # nls_session_parameters is not available in some Oracle + # modes like "mount mode". But then, v$nls_parameters is not + # available if the connection doesn't have SYSDBA priv. + # + # simplify the whole thing and just use the method that we were + # doing in the test suite already, selecting a number + + def output_type_handler( + cursor, name, defaultType, size, precision, scale + ): + return cursor.var( + self.dbapi.STRING, 255, arraysize=cursor.arraysize + ) + + cursor.outputtypehandler = output_type_handler + cursor.execute("SELECT 1.1 FROM DUAL") + value = cursor.fetchone()[0] + + decimal_char = value.lstrip("0")[1] + assert not decimal_char[0].isdigit() + + self._decimal_char = decimal_char + if self._decimal_char != ".": _detect_decimal = self._detect_decimal _to_decimal = self._to_decimal |
