Skip to content

Instantly share code, notes, and snippets.

@mjnaderi
Created January 10, 2022 08:36
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mjnaderi/7b86a2863eb15f9266729d9ffa68006a to your computer and use it in GitHub Desktop.
Save mjnaderi/7b86a2863eb15f9266729d9ffa68006a to your computer and use it in GitHub Desktop.
Compressed model field for Django

Please note that storing compressed binary values inside database has its own disadvantage. According to my experience using PostgreSQL, it increased the size of custom-format dump (pg_dump -Fc) by 60%.

import zlib
from django.db import models
from jsonfield.fields import JSONFieldMixin
class CompressedTextField(models.BinaryField):
"""
Model field for storing text as compressed binary data. Compression is done using zlib.
"""
def _check_str_default_value(self):
return []
def from_db_value(self, value, expression, connection):
if value is None:
return value
return zlib.decompress(value).decode()
def to_python(self, value):
if isinstance(value, bytes):
return zlib.decompress(value).decode()
return value
def get_prep_value(self, value):
return zlib.compress(value.encode())
class CompressedJSONField(JSONFieldMixin, models.BinaryField):
"""
Same as JSONField, but uses zlib to store value as compressed binary data.
"""
def _check_str_default_value(self):
return []
def from_db_value(self, value, expression, connection):
if value is None:
return value
return super().from_db_value(zlib.decompress(value).decode(), expression, connection)
def to_python(self, value):
if isinstance(value, bytes):
return super().to_python(zlib.decompress(value).decode())
return super().to_python(value)
def get_prep_value(self, value):
return zlib.compress(super().get_prep_value(value).encode())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment