0

I have a table that uses a custom_primary_key as an id which is a combination of 4 fields in the current table. I created a pre_save signal to concatenate the 4 fields to use it as an id. It is working fine with the save() and create() methods but I also wanted to implement the same logic with the bulk_create() method, how can I send each item in bulk_create to use the pre_save signal that generates the primary key value?

This is a sample code of what I'm trying to achieve but it seems that it is not reading the signals from the bulk_create method.

The error says: django.db.utils.IntegrityError: null value in column "id" violates not-null constraint DETAIL: Failing row contains (null, 1, 2, 3, 4).

class CustomManager(models.Manager):
    def bulk_create(self, objs, **kwargs):
        for obj in objs:
            pre_save.send(obj.__class__, instance=obj)
        return super().bulk_create(objs, **kwargs)
    

class MyModel(models.Model):
    objects = CustomManager()
    id = models.BigIntegerField(primary_key=True)
    field1 = models.IntegerField()
    field2 = models.IntegerField()
    field3 = models.IntegerField()
    field4 = models.IntegerField()


def generate_custom_id(sender, instance, **kwargs):
    instance.id = {}{}{}{}.format(instance.field1, instance.field2, instance.field3, instance.field4)

pre_save.connect(generate_custom_id, sender=MyModel)


   
michael ababao
  • 145
  • 2
  • 11
  • `bulk_create` is used to ***speed-up the DB insert operations***. If you implement the signal dispatcher *"somehow"* in it, it will be similar to *normal database insertion* – JPG Aug 28 '20 at 07:28
  • In short, if you implement the signal functionality in the `bulk_create(...)`, you will lose the `bulk_create()` functionality. – JPG Aug 28 '20 at 07:29
  • @ArakkalAbu I'm fine with a normal database insertion, I wanted to know if it is possible and how can I do it – michael ababao Aug 28 '20 at 07:32
  • add your complete error traceback – JPG Aug 28 '20 at 07:45
  • I said *"complete"*. BTW, Your code emits signals properly. The error might be because of how it gets handled in your `generate_custom_id` function – JPG Aug 28 '20 at 07:52
  • *" if you implement the signal functionality in the bulk_create(...), you will lose the bulk_create() functionality"*: Not really. You can emit signal for each object [once the DB operation is done](https://stackoverflow.com/a/30632974/2455888). It will still be faster than normal ORM insertion. – haccks Jun 18 '23 at 23:01

1 Answers1

0

bulk_create method does not send pre_save and post_save signals, if you want signals to be sent, use normal create method. link to Django documentation for bulk_create caveats

Neeraj
  • 783
  • 5
  • 8