mirror of https://github.com/django/django.git
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.
This commit is contained in:
parent
04a7ea3283
commit
cc0ac26f4a
|
@ -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)
|
||||||
|
|
Loading…
Reference in New Issue