Commit cc0ac26f authored by Anssi Kääriäinen's avatar Anssi Kääriäinen
Browse files

Fixed #19273 -- Fixed DB cache backend on pg 9.0+ and py3

There was a problem caused by Postgres 9.0+ having bytea_output default
value of 'hex' and cache backend inserting the content as 'bytes' into
a column of type TEXT. Fixed by converting the bytes value to a string
before insert.
parent 04a7ea32
Loading
Loading
Loading
Loading
+8 −4
Original line number Diff line number Diff line
@@ -11,7 +11,7 @@ except ImportError:
from django.conf import settings
from django.core.cache.backends.base import BaseCache
from django.db import connections, router, transaction, DatabaseError
from django.utils import timezone
from django.utils import timezone, six
from django.utils.encoding import force_bytes


@@ -104,7 +104,11 @@ class DatabaseCache(BaseDatabaseCache):
        if num > self._max_entries:
            self._cull(db, cursor, now)
        pickled = pickle.dumps(value, pickle.HIGHEST_PROTOCOL)
        encoded = base64.b64encode(pickled).strip()
        b64encoded = base64.b64encode(pickled)
        # The DB column is expecting a string, so make sure the value is a
        # string, not bytes. Refs #19274.
        if six.PY3:
            b64encoded = b64encoded.decode('latin1')
        cursor.execute("SELECT cache_key, expires FROM %s "
                       "WHERE cache_key = %%s" % table, [key])
        try:
@@ -113,11 +117,11 @@ class DatabaseCache(BaseDatabaseCache):
                    (mode == 'add' and result[1] < now)):
                cursor.execute("UPDATE %s SET value = %%s, expires = %%s "
                               "WHERE cache_key = %%s" % table,
                               [encoded, connections[db].ops.value_to_db_datetime(exp), key])
                               [b64encoded, connections[db].ops.value_to_db_datetime(exp), key])
            else:
                cursor.execute("INSERT INTO %s (cache_key, value, expires) "
                               "VALUES (%%s, %%s, %%s)" % table,
                               [key, encoded, connections[db].ops.value_to_db_datetime(exp)])
                               [key, b64encoded, connections[db].ops.value_to_db_datetime(exp)])
        except DatabaseError:
            # To be threadsafe, updates/inserts are allowed to fail silently
            transaction.rollback_unless_managed(using=db)