Skip to main content

Use PostgreSQL large objects for file storage

Project description

Use PostgreSQL large objects for file storage

This storage is created to store important files that belong to a user. It should not be used to store publicly available files or videos. The main benefit is that it works with transaction and you can create or delete a file and be confident that the file will still exist if the transaction is rolled back.

When the storage saves a file, a new filename with the template .<original_extension> is always created and the attribute upload_to is not used.

You can use DbFileIO without a storage.

The settings:

  • PG_LO_STORAGE_DB_FOR_READ - a database for read files (default is default)
  • PG_LO_STORAGE_DB_FOR_WRITE - a database for create and write files (default is default)

Example

Add model:

from django.db import models
from django.db.models.signals import post_delete, post_init, post_save
from django.dispatch import receiver
from pg_lo_storage.fields import DbFileField
from pg_lo_storage.storage import db_file_storage, DbFileStorage

class Invoice(models.Model):
    owner = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
    # data = DbFileField(storage=DbFileStorage("/invoice"), null=True, blank=True)
    data = models.FileField(storage=DbFileStorage("/invoice"), null=True, blank=True)

@receiver(post_init, sender=Invoice)
def user_file_initialized(sender, instance: Invoice, **kwargs):
    instance._lo_prev_state = {
        'data': instance.data.name if instance.data else None,
    }

@receiver(post_save, sender=Invoice)
def user_file_saved(sender, instance: Invoice, created: bool, **kwargs):
    # this is safe because large objects support transactions
    if not created and hasattr(instance, '_lo_prev_state'):
        state = instance._lo_prev_state
        if state.get('data'):
            instance.data.storage.delete(state['data'])

@receiver(post_delete, sender=Invoice)
def user_file_deleted(sender, instance: Invoice, **kwargs):
    # this is safe because large objects support transactions
    if instance.data:
        instance.data.storage.delete(instance.data.name)

Add function to serve files:

from django.http import HttpResponseForbidden
from pg_lo_storage.views import db_serve

@login_required
def invlice_serve(request: HttpRequest, filename: str) -> HttpResponse:
    if not Invoice.objects.filter(user=request.user, data=filename).exists():
        return HttpResponseForbidden()
    return db_serve(request, filename)

Work as a file:

from django.db import transaction
from pg_lo_storage.storage import DbFileIO

@transaction.atomic
def write(loid: int, data: bytes, pos: int) -> int:
    # DbFileIO work only with transactions
    with DbFileIO(loid, "wb") as file:
        file.seek(pos)
        file.write(data)
        return file.loid

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pg_lo_storage-0.2.2.tar.gz (16.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pg_lo_storage-0.2.2-py3-none-any.whl (8.5 kB view details)

Uploaded Python 3

File details

Details for the file pg_lo_storage-0.2.2.tar.gz.

File metadata

  • Download URL: pg_lo_storage-0.2.2.tar.gz
  • Upload date:
  • Size: 16.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for pg_lo_storage-0.2.2.tar.gz
Algorithm Hash digest
SHA256 788d72800329723b166fc85bdcff639d07ebfc63d7b35f2e6505dbd20f49828d
MD5 80f18ce7648fdff4a56c9855b4d1da92
BLAKE2b-256 077e2e5be2839080f9e5e2c4ae112472638ddda916673ecd87af1b979ed6a4cd

See more details on using hashes here.

Provenance

The following attestation bundles were made for pg_lo_storage-0.2.2.tar.gz:

Publisher: python-publish.yml on bibenga/pg-lo-storage

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pg_lo_storage-0.2.2-py3-none-any.whl.

File metadata

  • Download URL: pg_lo_storage-0.2.2-py3-none-any.whl
  • Upload date:
  • Size: 8.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for pg_lo_storage-0.2.2-py3-none-any.whl
Algorithm Hash digest
SHA256 e08c9172c6848beb3f9cd11ecf11527dddcc05f340772309723cc2f85b8d66c6
MD5 1c16c1658b8674f297c9c0809bbe40ea
BLAKE2b-256 6a1b7c7b4caaf1c29764dab36c476dae8c29c6e71cbc890b0ee600cdc7ff9504

See more details on using hashes here.

Provenance

The following attestation bundles were made for pg_lo_storage-0.2.2-py3-none-any.whl:

Publisher: python-publish.yml on bibenga/pg-lo-storage

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page