summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/dialects
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2022-10-31 15:09:34 -0400
committerMike Bayer <mike_mp@zzzcomputing.com>2022-11-01 17:05:52 -0400
commit32b2b31da2017fae8fcb759a52ad3d7081dec933 (patch)
tree7ddcf1583f8bf34e0d1d441f20240f1193629966 /lib/sqlalchemy/dialects
parent66f3533de86506327c753c1ea80b121692535745 (diff)
downloadsqlalchemy-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.py31
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