Commit 74c799d2 authored by Malcolm Tredinnick's avatar Malcolm Tredinnick
Browse files

[1.0.X] Fixed #9307 -- Added the ability to pickle the Query class used 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
parent 0a1aafa5
Loading
Loading
Loading
Loading
+26 −0
Original line number Diff line number Diff line
@@ -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 query_class(QueryClass, Database):

    _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
+5 −3
Original line number Diff line number Diff line
@@ -27,9 +27,9 @@ try:
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 @@ class Query(object):
# 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'):
    """