NilCoalescing / djangochannelsrestframework

A Rest-framework for websockets using Django channels-v4
https://djangochannelsrestframework.readthedocs.io/en/latest/
MIT License
613 stars 86 forks source link

[Feature] Add support to more optimally manually send bulk create events over the existing infra #193

Open ternyavsky opened 1 year ago

ternyavsky commented 1 year ago

I'm using a djangochannelsrestframework and I'm trying to make an observer on a model whose data is created using bulk_create. My Observer doesn't fire on BulkCreate, but when I create only one object, everything works fine. Is it possible to make an observer using bulk_create??

hishnash commented 1 year ago

The issue with bulk create is that Django dees not send the standard signals.

It could be made to work but only for Postgres as the database, since bulk create with PG returns all of the new object identifiers but other DBs do not.

https://docs.djangoproject.com/en/3.2/_modules/django/db/models/query/

        # We currently set the primary keys on the objects when using
        # PostgreSQL via the RETURNING ID clause.

If you are using PG therefore you can do the following but it will require calling the post_save directly once for each created object (so might be very heavy if your creating a LOT of objects)

created_objects = Entry.objects.bulk_create(myOBJList)

for obj in created_objects:
    MyConsumer.my_observer_method.post_save_receiver(user, created=True)

The my_observer_method is the method you have decorated with @model_observer.

( if your objects have primary keys set by you and not the db, eg UUIDs for example, or you do not use the PK in the model observer seraliaizer but something else like a slug you could use the above for DB other than just PG)

Not this needs to be called in a db sync thread so call it directly after calling bulk_create. This should work even if you are within a transition 🤞 (e.g it will delay sending the messages until the transition commits).


And alternative is within your consumer to directly subscribe to a custom channel group just for bulk create updates (so that you can send a single message for all the updated items) and then inform the subscribed user of this. (if your doing bulk create of 50+ I would suggest doing that). I you need help with that let my know I can create a little sample for you.

SemyonPanshin commented 8 months ago

Please provide an example of a subscription to bulk update

hishnash commented 7 months ago

Implementing subscriptions for bulk updates presents similar challenges to those encountered with bulk creation, primarily due to the absence of a straightforward Django signal for such operations. As a result, each object updated would necessitate a manual invocation of the update function, undermining the efficiency of bulk updates by necessitating subsequent database loads to retrieve each updated instance.

Looking ahead, there's a vision to enhance functionality by integrating with PostgreSQL's notification and subscription system. This would enable the deployment of an on-commit hook for database tables, effectively responding to bulk updates. However, developing this feature to be production-ready represents a significant undertaking and would be exclusive to PostgreSQL, potentially meriting a separate project altogether.