#36911: bulk_update() incorrectly allows updating GeneratedField (silent 
failure on
SQLite)
-------------------------------------+-------------------------------------
     Reporter:  jaffar Khan          |                     Type:  Bug
       Status:  new                  |                Component:  Database
                                     |  layer (models, ORM)
      Version:  dev                  |                 Severity:  Normal
     Keywords:  bulk_update          |             Triage Stage:
  GeneratedField                     |  Unreviewed
    Has patch:  0                    |      Needs documentation:  0
  Needs tests:  0                    |  Patch needs improvement:  0
Easy pickings:  0                    |                    UI/UX:  0
-------------------------------------+-------------------------------------
 Currently, bulk_update() does not validate if the fields provided in the
 fields=[...] argument are GeneratedField instances.

 Model:
 {{{
     class Product(models.Model):
         price = models.IntegerField()
         quantity = models.IntegerField()
         total = models.GeneratedField(
             expression=models.F("price") * models.F("quantity"),
             output_field=models.IntegerField(),
             db_persist=True,
         )
 }}}

 test function:
 {{{
 def run_test():

     # Create product
     p = Product.objects.create(price=10, quantity=2)

     p.total = 9999

     try:
         Product.objects.bulk_update([p], fields=["total"])
         print("silent failure")

     except Exception as e:
         print(f"CRASH: {e}")
 }}}
 output:
 **silent failure**

 If a developer accidentally includes a **GeneratedField** in
 **bulk_update()**, Django attempts to include it in the SQL UPDATE
 statement.
 On SQLite, this results in a silent failure (no error is raised, but the
 value is obviously not updated as it is generated).
 On strict databases (like PostgreSQL), this likely results in an
 OperationalError.

 Django should raise a FieldError immediately when **bulk_update()** is
 called with a **GeneratedField**, similar to how it handles other read-
 only fields or invalid field names.
-- 
Ticket URL: <https://code.djangoproject.com/ticket/36911>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion visit 
https://groups.google.com/d/msgid/django-updates/0107019c423d4c9f-e9948c3e-6201-459f-811f-b3edfb449f33-000000%40eu-central-1.amazonses.com.

Reply via email to