diff options
Diffstat (limited to 'lib/sqlalchemy/dialects/oracle')
| -rw-r--r-- | lib/sqlalchemy/dialects/oracle/base.py | 28 | ||||
| -rw-r--r-- | lib/sqlalchemy/dialects/oracle/cx_oracle.py | 72 |
2 files changed, 25 insertions, 75 deletions
diff --git a/lib/sqlalchemy/dialects/oracle/base.py b/lib/sqlalchemy/dialects/oracle/base.py index 5a43205df..229a54b95 100644 --- a/lib/sqlalchemy/dialects/oracle/base.py +++ b/lib/sqlalchemy/dialects/oracle/base.py @@ -10,7 +10,7 @@ r""" :name: Oracle :full_support: 11.2, 18c :normal_support: 11+ - :best_effort: 8+ + :best_effort: 9+ Auto Increment Behavior @@ -341,6 +341,9 @@ and specify "passive_updates=False" on each relationship(). Oracle 8 Compatibility ---------------------- +.. warning:: The status of Oracle 8 compatibility is not known for SQLAlchemy + 2.0. + When Oracle 8 is detected, the dialect internally configures itself to the following behaviors: @@ -349,16 +352,12 @@ following behaviors: makes use of Oracle's (+) operator. * the NVARCHAR2 and NCLOB datatypes are no longer generated as DDL when - the :class:`~sqlalchemy.types.Unicode` is used - VARCHAR2 and CLOB are - issued instead. This because these types don't seem to work correctly on - Oracle 8 even though they are available. The - :class:`~sqlalchemy.types.NVARCHAR` and + the :class:`~sqlalchemy.types.Unicode` is used - VARCHAR2 and CLOB are issued + instead. This because these types don't seem to work correctly on Oracle 8 + even though they are available. The :class:`~sqlalchemy.types.NVARCHAR` and :class:`~sqlalchemy.dialects.oracle.NCLOB` types will always generate NVARCHAR2 and NCLOB. -* the "native unicode" mode is disabled when using cx_oracle, i.e. SQLAlchemy - encodes all Python unicode objects to "string" before passing in as bind - parameters. Synonym/DBLINK Reflection ------------------------- @@ -1439,8 +1438,6 @@ class OracleDialect(default.DefaultDialect): name = "oracle" supports_statement_cache = True supports_alter = True - supports_unicode_statements = False - supports_unicode_binds = False max_identifier_length = 128 supports_simple_order_by_label = False @@ -1576,17 +1573,6 @@ class OracleDialect(default.DefaultDialect): # use the default return None - def _check_unicode_returns(self, connection): - additional_tests = [ - expression.cast( - expression.literal_column("'test nvarchar2 returns'"), - sqltypes.NVARCHAR(60), - ) - ] - return super(OracleDialect, self)._check_unicode_returns( - connection, additional_tests - ) - _isolation_lookup = ["READ COMMITTED", "SERIALIZABLE"] def get_isolation_level(self, connection): diff --git a/lib/sqlalchemy/dialects/oracle/cx_oracle.py b/lib/sqlalchemy/dialects/oracle/cx_oracle.py index 590c9d47c..23f619a12 100644 --- a/lib/sqlalchemy/dialects/oracle/cx_oracle.py +++ b/lib/sqlalchemy/dialects/oracle/cx_oracle.py @@ -119,7 +119,7 @@ itself. These options are always passed directly to :func:`_sa.create_engine` , such as:: e = create_engine( - "oracle+cx_oracle://user:pass@dsn", coerce_to_unicode=False) + "oracle+cx_oracle://user:pass@dsn", coerce_to_decimal=False) The parameters accepted by the cx_oracle dialect are as follows: @@ -130,8 +130,6 @@ The parameters accepted by the cx_oracle dialect are as follows: * ``auto_convert_lobs`` - defaults to True; See :ref:`cx_oracle_lob`. -* ``coerce_to_unicode`` - see :ref:`cx_oracle_unicode` for detail. - * ``coerce_to_decimal`` - see :ref:`cx_oracle_numeric` for detail. * ``encoding_errors`` - see :ref:`cx_oracle_unicode_encoding_errors` for detail. @@ -210,8 +208,7 @@ Unicode ------- As is the case for all DBAPIs under Python 3, all strings are inherently -Unicode strings. Under Python 2, cx_Oracle also supports Python Unicode -objects directly. In all cases however, the driver requires an explicit +Unicode strings. In all cases however, the driver requires an explicit encoding configuration. Ensuring the Correct Client Encoding @@ -264,25 +261,6 @@ SQLAlchemy dialect to use NCHAR/NCLOB for the :class:`.Unicode` / unless the ``use_nchar_for_unicode=True`` is passed to the dialect when :func:`_sa.create_engine` is called. -Unicode Coercion of result rows under Python 2 -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -When result sets are fetched that include strings, under Python 3 the cx_Oracle -DBAPI returns all strings as Python Unicode objects, since Python 3 only has a -Unicode string type. This occurs for data fetched from datatypes such as -VARCHAR2, CHAR, CLOB, NCHAR, NCLOB, etc. In order to provide cross- -compatibility under Python 2, the SQLAlchemy cx_Oracle dialect will add -Unicode-conversion to string data under Python 2 as well. Historically, this -made use of converters that were supplied by cx_Oracle but were found to be -non-performant; SQLAlchemy's own converters are used for the string to Unicode -conversion under Python 2. To disable the Python 2 Unicode conversion for -VARCHAR2, CHAR, and CLOB, the flag ``coerce_to_unicode=False`` can be passed to -:func:`_sa.create_engine`. - -.. versionchanged:: 1.3 Unicode conversion is applied to all string values - by default under python 2. The ``coerce_to_unicode`` now defaults to True - and can be set to False to disable the Unicode coercion of strings that are - delivered as VARCHAR2/CHAR/CLOB data. .. _cx_oracle_unicode_encoding_errors: @@ -855,9 +833,6 @@ class OracleDialect_cx_oracle(OracleDialect): supports_sane_rowcount = True supports_sane_multi_rowcount = True - supports_unicode_statements = True - supports_unicode_binds = True - use_setinputsizes = True driver = "cx_oracle" @@ -892,6 +867,8 @@ class OracleDialect_cx_oracle(OracleDialect): _cx_oracle_threaded = None + _cursor_var_unicode_kwargs = util.immutabledict() + @util.deprecated_params( threaded=( "1.3", @@ -906,7 +883,6 @@ class OracleDialect_cx_oracle(OracleDialect): def __init__( self, auto_convert_lobs=True, - coerce_to_unicode=True, coerce_to_decimal=True, arraysize=50, encoding_errors=None, @@ -917,10 +893,13 @@ class OracleDialect_cx_oracle(OracleDialect): OracleDialect.__init__(self, **kwargs) self.arraysize = arraysize self.encoding_errors = encoding_errors + if encoding_errors: + self._cursor_var_unicode_kwargs = { + "encodingErrors": encoding_errors + } if threaded is not None: self._cx_oracle_threaded = threaded self.auto_convert_lobs = auto_convert_lobs - self.coerce_to_unicode = coerce_to_unicode self.coerce_to_decimal = coerce_to_decimal if self._use_nchar_for_unicode: self.colspecs = self.colspecs.copy() @@ -939,6 +918,13 @@ class OracleDialect_cx_oracle(OracleDialect): "cx_Oracle version 5.2 and above are supported" ) + if encoding_errors and self.cx_oracle_ver < (6, 4): + util.warn( + "cx_oracle version %r does not support encodingErrors" + % (self.cx_oracle_ver,) + ) + self._cursor_var_unicode_kwargs = util.immutabledict() + self._include_setinputsizes = { cx_Oracle.DATETIME, cx_Oracle.NCLOB, @@ -974,19 +960,6 @@ class OracleDialect_cx_oracle(OracleDialect): self._is_cx_oracle_6 = self.cx_oracle_ver >= (6,) - @property - def _cursor_var_unicode_kwargs(self): - if self.encoding_errors: - if self.cx_oracle_ver >= (6, 4): - return {"encodingErrors": self.encoding_errors} - else: - util.warn( - "cx_oracle version %r does not support encodingErrors" - % (self.cx_oracle_ver,) - ) - - return {} - def _parse_cx_oracle_ver(self, version): m = re.match(r"(\d+)\.(\d+)(?:\.(\d+))?", version) if m: @@ -1002,9 +975,6 @@ class OracleDialect_cx_oracle(OracleDialect): def initialize(self, connection): super(OracleDialect_cx_oracle, self).initialize(connection) - if self._is_oracle_8: - self.supports_unicode_binds = False - self._detect_decimal_char(connection) def get_isolation_level(self, connection): @@ -1141,9 +1111,10 @@ class OracleDialect_cx_oracle(OracleDialect): cursor, name, default_type, size, precision, scale ) - # allow all strings to come back natively as Unicode + # if unicode options were specified, add a decoder, otherwise + # cx_Oracle should return Unicode elif ( - dialect.coerce_to_unicode + dialect._cursor_var_unicode_kwargs and default_type in ( cx_Oracle.STRING, @@ -1338,13 +1309,6 @@ class OracleDialect_cx_oracle(OracleDialect): if dbtype ) - if not self.supports_unicode_binds: - # oracle 8 only - collection = ( - (self.dialect._encoder(key)[0], dbtype) - for key, dbtype in collection - ) - cursor.setinputsizes(**{key: dbtype for key, dbtype in collection}) def do_recover_twophase(self, connection): |
