Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

[1.0.X] Fixed #5543: callproc() and friends now work with Oracle and …

…our FormatStylePlaceholderCursor.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.0.X@9768 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit f0e35e1bbe9c5e35717482c5c5df11abfc70fd76 1 parent 4268ef3
@mboersma mboersma authored
View
35 django/db/backends/oracle/base.py
@@ -291,10 +291,6 @@ def _cursor(self, settings):
pass
if not cursor:
cursor = FormatStylePlaceholderCursor(self.connection)
- # Necessary to retrieve decimal values without rounding error.
- cursor.numbersAsStrings = True
- # Default arraysize of 1 is highly sub-optimal.
- cursor.arraysize = 100
return cursor
@@ -320,7 +316,7 @@ def __init__(self, param, charset, strings_only=False):
self.input_size = None
-class FormatStylePlaceholderCursor(Database.Cursor):
+class FormatStylePlaceholderCursor(object):
"""
Django uses "format" (e.g. '%s') style placeholders, but Oracle uses ":var"
style. This fixes it -- but note that if you want to use a literal "%s" in
@@ -331,6 +327,13 @@ class FormatStylePlaceholderCursor(Database.Cursor):
"""
charset = 'utf-8'
+ def __init__(self, connection):
+ self.cursor = connection.cursor()
+ # Necessary to retrieve decimal values without rounding error.
+ self.cursor.numbersAsStrings = True
+ # Default arraysize of 1 is highly sub-optimal.
+ self.cursor.arraysize = 100
+
def _format_params(self, params):
return tuple([OracleParam(p, self.charset, True) for p in params])
@@ -360,8 +363,7 @@ def execute(self, query, params=None):
query = smart_str(query, self.charset) % tuple(args)
self._guess_input_sizes([params])
try:
- return Database.Cursor.execute(self, query,
- self._param_generator(params))
+ return self.cursor.execute(query, self._param_generator(params))
except DatabaseError, e:
# cx_Oracle <= 4.4.0 wrongly raises a DatabaseError for ORA-01400.
if e.args[0].code == 1400 and not isinstance(e, IntegrityError):
@@ -384,7 +386,7 @@ def executemany(self, query, params=None):
formatted = [self._format_params(i) for i in params]
self._guess_input_sizes(formatted)
try:
- return Database.Cursor.executemany(self, query,
+ return self.cursor.executemany(query,
[self._param_generator(p) for p in formatted])
except DatabaseError, e:
# cx_Oracle <= 4.4.0 wrongly raises a DatabaseError for ORA-01400.
@@ -393,7 +395,7 @@ def executemany(self, query, params=None):
raise e
def fetchone(self):
- row = Database.Cursor.fetchone(self)
+ row = self.cursor.fetchone()
if row is None:
return row
return self._rowfactory(row)
@@ -402,17 +404,17 @@ def fetchmany(self, size=None):
if size is None:
size = self.arraysize
return tuple([self._rowfactory(r)
- for r in Database.Cursor.fetchmany(self, size)])
+ for r in self.cursor.fetchmany(size)])
def fetchall(self):
return tuple([self._rowfactory(r)
- for r in Database.Cursor.fetchall(self)])
+ for r in self.cursor.fetchall()])
def _rowfactory(self, row):
# Cast numeric values as the appropriate Python type based upon the
# cursor description, and convert strings to unicode.
casted = []
- for value, desc in zip(row, self.description):
+ for value, desc in zip(row, self.cursor.description):
if value is not None and desc[1] is Database.NUMBER:
precision, scale = desc[4:6]
if scale == -127:
@@ -447,6 +449,15 @@ def _rowfactory(self, row):
casted.append(value)
return tuple(casted)
+ def __getattr__(self, attr):
+ if attr in self.__dict__:
+ return self.__dict__[attr]
+ else:
+ return getattr(self.cursor, attr)
+
+ def __iter__(self):
+ return iter(self.cursor)
+
def to_unicode(s):
"""
View
26 tests/regressiontests/backends/tests.py
@@ -0,0 +1,26 @@
+# -*- coding: utf-8 -*-
+
+# Unit tests for specific database backends.
+
+import unittest
+
+from django.db import connection
+from django.conf import settings
+
+
+class Callproc(unittest.TestCase):
+
+ def test_dbms_session(self):
+ # If the backend is Oracle, test that we can call a standard
+ # stored procedure through our cursor wrapper.
+ if settings.DATABASE_ENGINE == 'oracle':
+ cursor = connection.cursor()
+ cursor.callproc('DBMS_SESSION.SET_IDENTIFIER',
+ ['_django_testing!',])
+ return True
+ else:
+ return True
+
+
+if __name__ == '__main__':
+ unittest.main()
Please sign in to comment.
Something went wrong with that request. Please try again.