summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2017-03-13 12:27:51 -0400
committerMike Bayer <mike_mp@zzzcomputing.com>2017-03-13 14:16:42 -0400
commitfb33f9c54be842e191c893c91b3233cd1ae545bc (patch)
treeeb82e447b4a88c71764b579b192ebf201b6efd26 /lib/sqlalchemy
parent1da9d3752160430c91534a8868ceb8c5ad1451d4 (diff)
downloadsqlalchemy-fb33f9c54be842e191c893c91b3233cd1ae545bc.tar.gz
Repair _execute_scalar for WITH_UNICODE mode
cx_Oracle 5.3 seems to code this flag ON now, so remove the warning and ensure WITH_UNICODE handling works. Additionally, the XE setup on jenkins is having more problems here, in particular low-connections mode is causing cx_Oracle to fail more frequently now. Turning off low-connections fixes those but then we get the TNS errors, so adding an emergency "retry" flag that is not yet a feature available to users. Real world applications are not dropping/creating thousands of tables the way our test suite is. Change-Id: Ie95b0e697276c404d3264c2e624e870463d966d6 Fixes: #3937
Diffstat (limited to 'lib/sqlalchemy')
-rw-r--r--lib/sqlalchemy/dialects/oracle/cx_oracle.py39
-rw-r--r--lib/sqlalchemy/testing/provision.py6
2 files changed, 30 insertions, 15 deletions
diff --git a/lib/sqlalchemy/dialects/oracle/cx_oracle.py b/lib/sqlalchemy/dialects/oracle/cx_oracle.py
index 5d1167684..9b3e3b8a1 100644
--- a/lib/sqlalchemy/dialects/oracle/cx_oracle.py
+++ b/lib/sqlalchemy/dialects/oracle/cx_oracle.py
@@ -298,6 +298,7 @@ import random
import collections
import decimal
import re
+import time
class _OracleNumeric(sqltypes.Numeric):
@@ -621,9 +622,9 @@ class OracleExecutionContext_cx_oracle_with_unicode(
OracleExecutionContext_cx_oracle.__init__(self, *arg, **kw)
self.statement = util.text_type(self.statement)
- def _execute_scalar(self, stmt):
+ def _execute_scalar(self, stmt, type_):
return super(OracleExecutionContext_cx_oracle_with_unicode, self).\
- _execute_scalar(util.text_type(stmt))
+ _execute_scalar(util.text_type(stmt), type_)
class ReturningResultProxy(_result.FullyBufferedResultProxy):
@@ -692,7 +693,8 @@ class OracleDialect_cx_oracle(OracleDialect):
allow_twophase=True,
coerce_to_decimal=True,
coerce_to_unicode=False,
- arraysize=50, **kwargs):
+ arraysize=50, _retry_on_12516=False,
+ **kwargs):
OracleDialect.__init__(self, **kwargs)
self.threaded = threaded
self.arraysize = arraysize
@@ -701,6 +703,7 @@ class OracleDialect_cx_oracle(OracleDialect):
hasattr(self.dbapi, 'TIMESTAMP')
self.auto_setinputsizes = auto_setinputsizes
self.auto_convert_lobs = auto_convert_lobs
+ self._retry_on_12516 = _retry_on_12516
if hasattr(self.dbapi, 'version'):
self.cx_oracle_ver = tuple([int(x) for x in
@@ -748,18 +751,8 @@ class OracleDialect_cx_oracle(OracleDialect):
if util.py2k:
# There's really no reason to run with WITH_UNICODE under
- # Python 2.x. Give the user a hint.
- util.warn(
- "cx_Oracle is compiled under Python 2.xx using the "
- "WITH_UNICODE flag. Consider recompiling cx_Oracle "
- "without this flag, which is in no way necessary for "
- "full support of Unicode. Otherwise, all string-holding "
- "bind parameters must be explicitly typed using "
- "SQLAlchemy's String type or one of its subtypes,"
- "or otherwise be passed as Python unicode. "
- "Plain Python strings passed as bind parameters will be "
- "silently corrupted by cx_Oracle."
- )
+ # Python 2.x. However as of cx_oracle 5.3 it seems to be
+ # set to ON for default builds
self.execution_ctx_cls = \
OracleExecutionContext_cx_oracle_with_unicode
else:
@@ -785,6 +778,22 @@ class OracleDialect_cx_oracle(OracleDialect):
import cx_Oracle
return cx_Oracle
+ def connect(self, *cargs, **cparams):
+ if self._retry_on_12516:
+ # emergency flag for the SQLAlchemy test suite, which has
+ # decreased in stability since cx_oracle 5.3; generalized
+ # "retry on connect" functionality is part of an upcoming
+ # SQLAlchemy feature
+ try:
+ return self.dbapi.connect(*cargs, **cparams)
+ except self.dbapi.DatabaseError as err:
+ if "ORA-12516" in str(err):
+ time.sleep(2)
+ return self.dbapi.connect(*cargs, **cparams)
+ else:
+ return super(OracleDialect_cx_oracle, self).connect(
+ *cargs, **cparams)
+
def initialize(self, connection):
super(OracleDialect_cx_oracle, self).initialize(connection)
if self._is_oracle_8:
diff --git a/lib/sqlalchemy/testing/provision.py b/lib/sqlalchemy/testing/provision.py
index 23d504b84..7e4454465 100644
--- a/lib/sqlalchemy/testing/provision.py
+++ b/lib/sqlalchemy/testing/provision.py
@@ -126,6 +126,7 @@ def _mssql_update_db_opts(db_url, db_opts):
db_opts['legacy_schema_aliasing'] = False
+
@_follower_url_from_main.for_db("sqlite")
def _sqlite_follower_url_from_main(url, ident):
url = sa_url.make_url(url)
@@ -270,6 +271,11 @@ def _oracle_drop_db(cfg, eng, ident):
_ora_drop_ignore(conn, "%s_ts2" % ident)
+@_update_db_opts.for_db("oracle")
+def _oracle_update_db_opts(db_url, db_opts):
+ db_opts['_retry_on_12516'] = True
+
+
def reap_oracle_dbs(eng, idents_file):
log.info("Reaping Oracle dbs...")
with eng.connect() as conn: