Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Fixed #9307 -- Added the ability to pickle the Query class used by th…

…e 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.


git-svn-id: http://code.djangoproject.com/svn/django/trunk@9272 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit 3dfbaae32b2e87fd1f47b569f973fb3f76602137 1 parent 03fcf19
Malcolm Tredinnick authored October 24, 2008
26  django/db/backends/oracle/query.py
@@ -25,6 +25,18 @@ def query_class(QueryClass, Database):
25 25
         pass
26 26
 
27 27
     class OracleQuery(QueryClass):
  28
+        def __reduce__(self):
  29
+            """
  30
+            Enable pickling for this class (normal pickling handling doesn't
  31
+            work as Python can only pickle module-level classes by default).
  32
+            """
  33
+            if hasattr(QueryClass, '__getstate__'):
  34
+                assert hasattr(QueryClass, '__setstate__')
  35
+                data = self.__getstate__()
  36
+            else:
  37
+                data = self.__dict__
  38
+            return (unpickle_query_class, (QueryClass,), data)
  39
+
28 40
         def resolve_columns(self, row, fields=()):
29 41
             # If this query has limit/offset information, then we expect the
30 42
             # 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):
120 132
 
121 133
     _classes[QueryClass] = OracleQuery
122 134
     return OracleQuery
  135
+
  136
+def unpickle_query_class(QueryClass):
  137
+    """
  138
+    Utility function, called by Python's unpickling machinery, that handles
  139
+    unpickling of Oracle Query subclasses.
  140
+    """
  141
+    # XXX: Would be nice to not have any dependency on cx_Oracle here. Since
  142
+    # modules can't be pickled, we need a way to know to load the right module.
  143
+    import cx_Oracle
  144
+
  145
+    klass = query_class(QueryClass, cx_Oracle)
  146
+    return klass.__new__(klass)
  147
+unpickle_query_class.__safe_for_unpickling__ = True
  148
+
8  django/db/models/sql/query.py
@@ -27,9 +27,9 @@
27 27
 except NameError:
28 28
     from sets import Set as set     # Python 2.3 fallback
29 29
 
30  
-__all__ = ['Query']
  30
+__all__ = ['Query', 'BaseQuery']
31 31
 
32  
-class Query(object):
  32
+class BaseQuery(object):
33 33
     """
34 34
     A single SQL query.
35 35
     """
@@ -1757,7 +1757,9 @@ def execute_sql(self, result_type=MULTI):
1757 1757
 # Use the backend's custom Query class if it defines one. Otherwise, use the
1758 1758
 # default.
1759 1759
 if connection.features.uses_custom_query_class:
1760  
-    Query = connection.ops.query_class(Query)
  1760
+    Query = connection.ops.query_class(BaseQuery)
  1761
+else:
  1762
+    Query = BaseQuery
1761 1763
 
1762 1764
 def get_order_dir(field, default='ASC'):
1763 1765
     """

0 notes on commit 3dfbaae

Please sign in to comment.
Something went wrong with that request. Please try again.