- Notifications
You must be signed in to change notification settings - Fork 222
Open
Description
In a django project with a database router and read-only databases, the delete_expired method may try to perform raw_delete() using a read-only database, resulting in an Internal Error: "ReadOnlySqlTransaction - cannot execute DELETE in a read-only transaction".
def delete_expired(self, expires): """Delete all expired results.""" with transaction.atomic(using=self.db): raw_delete(queryset=self.get_all_expired(expires))My Database Router:
import random from django.conf import settings class CustomRouter: def db_for_read(self, model, **hints): """ Return either default or one of the replicas """ db_read = [ "default", ] if settings.REPLICA1_URL is not None: db_read.append("replica1") if settings.REPLICA2_URL is not None: db_read.append("replica2") return random.choice(db_read) def db_for_write(self, model, **hints): # Always return the default database return "default" def allow_relation(self, obj1, obj2, **hints): return True def allow_migrate(self, db, app_label, model_name=None, **hints): return TrueOccasionally, django-celery-results will attempt to conduct delete_expired using one of my replica databases:
connection: <DatabaseWrapper vendor='postgresql' alias='replica1'>
Recommend changing the using argument of the atomic transaction in delete_expired to explicitly use the writable database specified in the router.
matmunn
Metadata
Metadata
Assignees
Labels
No labels