summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristoph Zwerschke <cito@online.de>2014-02-27 21:15:21 +0100
committerChristoph Zwerschke <cito@online.de>2014-02-27 21:15:21 +0100
commitc4dede6e7c1420aacc54c9c326bf3a834dff45c7 (patch)
tree776dbf2cf0cfa26b9868832201a6ff3a5c3786e3
parentc2f86c92b1fbb4e855161bd509d3057f86ed7a74 (diff)
downloadsqlalchemy-pr/74.tar.gz
Restore coercion to unicode with cx_Oracle.pr/74
This feature is now turned off by default.
-rw-r--r--lib/sqlalchemy/dialects/oracle/cx_oracle.py20
-rw-r--r--test/dialect/test_oracle.py10
2 files changed, 27 insertions, 3 deletions
diff --git a/lib/sqlalchemy/dialects/oracle/cx_oracle.py b/lib/sqlalchemy/dialects/oracle/cx_oracle.py
index 9a632cb0a..0e9d7175e 100644
--- a/lib/sqlalchemy/dialects/oracle/cx_oracle.py
+++ b/lib/sqlalchemy/dialects/oracle/cx_oracle.py
@@ -70,7 +70,12 @@ unicode by using outputtypehandlers, SQLAlchemy has observed that usage
of a unicode-converting outputtypehandler in Python 2 (not Python 3) incurs
significant performance overhead for all statements that deliver string
results, whether or not values contain non-ASCII characters. For this reason,
-SQLAlchemy as of 0.9.2 does not use cx_Oracle's outputtypehandlers for unicode conversion.
+SQLAlchemy as of 0.9.2 does not use cx_Oracle's outputtypehandlers for unicode
+conversion by default. If you want to use this feature anyway, you can enable
+it by passing the flag ``coerce_to_unicode=True`` to :func:`.create_engine`::
+
+ engine = create_engine("oracle+cx_oracle://dsn",
+ coerce_to_unicode=True)
Keeping in mind that any NVARCHAR or NCLOB type is returned as Python unicode
unconditionally, in order for VARCHAR values to be returned as Python unicode
@@ -90,6 +95,9 @@ SQL statement, use :func:`.text`::
performance bottleneck. SQLAlchemy's own unicode facilities are used
instead.
+.. versionadded:: 0.9.4
+ Add the ``coerce_to_unicode`` flag.
+
.. _cx_oracle_returning:
RETURNING Support
@@ -602,6 +610,7 @@ class OracleDialect_cx_oracle(OracleDialect):
threaded=True,
allow_twophase=True,
coerce_to_decimal=True,
+ coerce_to_unicode=False,
arraysize=50, **kwargs):
OracleDialect.__init__(self, **kwargs)
self.threaded = threaded
@@ -630,6 +639,11 @@ class OracleDialect_cx_oracle(OracleDialect):
self._cx_oracle_binary_types = types("BFILE", "CLOB", "NCLOB", "BLOB")
self.supports_unicode_binds = self.cx_oracle_ver >= (5, 0)
+ self.coerce_to_unicode = (
+ self.cx_oracle_ver >= (5, 0) and
+ coerce_to_unicode
+ )
+
self.supports_native_decimal = (
self.cx_oracle_ver >= (5, 0) and
coerce_to_decimal
@@ -773,6 +787,10 @@ class OracleDialect_cx_oracle(OracleDialect):
255,
outconverter=self._detect_decimal,
arraysize=cursor.arraysize)
+ # allow all strings to come back natively as Unicode
+ elif self.coerce_to_unicode and \
+ defaultType in (cx_Oracle.STRING, cx_Oracle.FIXED_CHAR):
+ return cursor.var(util.text_type, size, cursor.arraysize)
def on_connect(conn):
conn.outputtypehandler = output_type_handler
diff --git a/test/dialect/test_oracle.py b/test/dialect/test_oracle.py
index 8d0ff9776..660a2a5e9 100644
--- a/test/dialect/test_oracle.py
+++ b/test/dialect/test_oracle.py
@@ -1218,8 +1218,6 @@ class TypesTest(fixtures.TestBase):
assert isinstance(row[i], type_), '%r is not %r' \
% (row[i], type_)
-
-
def test_numeric_no_decimal_mode(self):
engine = testing_engine(options=dict(coerce_to_decimal=False))
value = engine.scalar("SELECT 5.66 FROM DUAL")
@@ -1228,6 +1226,14 @@ class TypesTest(fixtures.TestBase):
value = testing.db.scalar("SELECT 5.66 FROM DUAL")
assert isinstance(value, decimal.Decimal)
+ def test_coerce_to_unicode(self):
+ engine = testing_engine(options=dict(coerce_to_unicode=True))
+ value = engine.scalar("SELECT 'hello' FROM DUAL")
+ assert isinstance(value, util.text_type)
+
+ value = testing.db.scalar("SELECT 'hello' FROM DUAL")
+ assert isinstance(value, util.binary_type)
+
@testing.provide_metadata
def test_numerics_broken_inspection(self):
"""Numeric scenarios where Oracle type info is 'broken',