diff --git a/django/db/backends/oracle/query.py b/django/db/backends/oracle/query.py
index 85e2f68..c049004 100644
--- a/django/db/backends/oracle/query.py
+++ b/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=()):
             index_start = len(self.extra_select.keys())
             values = [self.convert_values(v, None) for v in row[:index_start]]
@@ -143,3 +155,17 @@ def query_class(QueryClass, Database):
 
     _classes[QueryClass] = OracleQuery
     return OracleQuery
+
+def unpickle_query_class(QueryClass):
+    """
+    Utility function for handling unpickling of Oracle Query subclasses. This
+    is called by Python's unpickling functions.
+    """
+    # FIXME: 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
+
