[1.5.x] 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.

Backpatch of [cc0ac26f4a].
This commit is contained in:
Anssi Kääriäinen 2012-11-10 18:39:59 +02:00
parent 48a2917d46
commit 825a793555
1 changed files with 8 additions and 4 deletions

View File

@ -11,7 +11,7 @@ except ImportError:
from django.conf import settings from django.conf import settings
from django.core.cache.backends.base import BaseCache from django.core.cache.backends.base import BaseCache
from django.db import connections, router, transaction, DatabaseError 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 from django.utils.encoding import force_bytes
@ -104,7 +104,11 @@ class DatabaseCache(BaseDatabaseCache):
if num > self._max_entries: if num > self._max_entries:
self._cull(db, cursor, now) self._cull(db, cursor, now)
pickled = pickle.dumps(value, pickle.HIGHEST_PROTOCOL) 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 " cursor.execute("SELECT cache_key, expires FROM %s "
"WHERE cache_key = %%s" % table, [key]) "WHERE cache_key = %%s" % table, [key])
try: try:
@ -113,11 +117,11 @@ class DatabaseCache(BaseDatabaseCache):
(mode == 'add' and result[1] < now)): (mode == 'add' and result[1] < now)):
cursor.execute("UPDATE %s SET value = %%s, expires = %%s " cursor.execute("UPDATE %s SET value = %%s, expires = %%s "
"WHERE cache_key = %%s" % table, "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: else:
cursor.execute("INSERT INTO %s (cache_key, value, expires) " cursor.execute("INSERT INTO %s (cache_key, value, expires) "
"VALUES (%%s, %%s, %%s)" % table, "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: except DatabaseError:
# To be threadsafe, updates/inserts are allowed to fail silently # To be threadsafe, updates/inserts are allowed to fail silently
transaction.rollback_unless_managed(using=db) transaction.rollback_unless_managed(using=db)