Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

[1.0.X] Fixed #9307 -- Added the ability to pickle the Query class us…

…ed by the

Oracle backend.

This allows Querysets to be cached for Oracle and should provide a model for
adding pickling support to other (external) database backends that need a
custom Query class.

Thanks to Justin Bronn for some assistance with this patch.

Backport of r9272 from trunk.


git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.0.X@9273 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit 74c799d21d6682eb0a0ed8fa25dc48787d5bfb86 1 parent 0a1aafa
@malcolmt malcolmt authored
View
26 django/db/backends/oracle/query.py
@@ -25,6 +25,18 @@ def query_class(QueryClass, Database):
pass
class OracleQuery(QueryClass):
+ def __reduce__(self):
+ """
+ Enable pickling for this class (normal pickling handling doesn't
+ work as Python can only pickle module-level classes by default).
+ """
+ if hasattr(QueryClass, '__getstate__'):
+ assert hasattr(QueryClass, '__setstate__')
+ data = self.__getstate__()
+ else:
+ data = self.__dict__
+ return (unpickle_query_class, (QueryClass,), data)
+
def resolve_columns(self, row, fields=()):
# If this query has limit/offset information, then we expect the
# first column to be an extra "_RN" column that we need to throw
@@ -120,3 +132,17 @@ def as_sql(self, with_limits=True, with_col_aliases=False):
_classes[QueryClass] = OracleQuery
return OracleQuery
+
+def unpickle_query_class(QueryClass):
+ """
+ Utility function, called by Python's unpickling machinery, that handles
+ unpickling of Oracle Query subclasses.
+ """
+ # XXX: Would be nice to not have any dependency on cx_Oracle here. Since
+ # modules can't be pickled, we need a way to know to load the right module.
+ import cx_Oracle
+
+ klass = query_class(QueryClass, cx_Oracle)
+ return klass.__new__(klass)
+unpickle_query_class.__safe_for_unpickling__ = True
+
View
8 django/db/models/sql/query.py
@@ -27,9 +27,9 @@
except NameError:
from sets import Set as set # Python 2.3 fallback
-__all__ = ['Query']
+__all__ = ['Query', 'BaseQuery']
-class Query(object):
+class BaseQuery(object):
"""
A single SQL query.
"""
@@ -1757,7 +1757,9 @@ def execute_sql(self, result_type=MULTI):
# Use the backend's custom Query class if it defines one. Otherwise, use the
# default.
if connection.features.uses_custom_query_class:
- Query = connection.ops.query_class(Query)
+ Query = connection.ops.query_class(BaseQuery)
+else:
+ Query = BaseQuery
def get_order_dir(field, default='ASC'):
"""
Please sign in to comment.
Something went wrong with that request. Please try again.