Optimize bulk updates of custom field values when custom fields are added/removed #10933

Closed
opened 2025-12-29 21:37:56 +01:00 by adam · 0 comments
Owner

Originally created by @jeremystretch on GitHub (Mar 21, 2025).

Originally assigned to: @jeremystretch on GitHub.

NetBox version

v4.2.5

Feature type

Change to existing functionality

Proposed functionality

This FR intends to capture an opportunity to improve performance when a custom field is added to or removed from a model which has many thousands of records. Whenever a custom field is added, its populate_initial_data() method is called to automatically populate the field's default value on all objects:

7db0765ed2/netbox/extras/models/customfields.py (L279-L289)

The current approach is suboptimal, as it requires loading each individual object into memory to effect the change. I believe we can optimize this by mutating the JSON data directly within the query:

from django.db.models import F, Func, Value
from django.db.models import JSONField

def bulk_update_cf_value(model, field_name, new_value):
    model.objects.update(
        custom_field_data=Func(
            F('custom_field_data'),
            Value([field_name]),
            Value(new_value, JSONField()),
            function='jsonb_set'
        )
    )

bulk_update_cf_value(Site, "test1", "abc123")

This allows us to update the value of a specific key for all objects without first loading each into memory.

Similar approaches will be needed for the remove_stale_data() and rename_object_data() methods on CustomField as well.

Use case

This should result in a dramatic reduction in the time required to bulk update custom field data, particularly when many thousands of records are affected.

Database changes

N/A

External dependencies

N/A

Originally created by @jeremystretch on GitHub (Mar 21, 2025). Originally assigned to: @jeremystretch on GitHub. ### NetBox version v4.2.5 ### Feature type Change to existing functionality ### Proposed functionality This FR intends to capture an opportunity to improve performance when a custom field is added to or removed from a model which has many thousands of records. Whenever a custom field is added, its `populate_initial_data()` method is called to automatically populate the field's default value on all objects: https://github.com/netbox-community/netbox/blob/7db0765ed2bf7098bab17cb71e389ffbfde34ceb/netbox/extras/models/customfields.py#L279-L289 The current approach is suboptimal, as it requires loading each individual object into memory to effect the change. I believe we can optimize this by mutating the JSON data directly within the query: ```python from django.db.models import F, Func, Value from django.db.models import JSONField def bulk_update_cf_value(model, field_name, new_value): model.objects.update( custom_field_data=Func( F('custom_field_data'), Value([field_name]), Value(new_value, JSONField()), function='jsonb_set' ) ) bulk_update_cf_value(Site, "test1", "abc123") ``` This allows us to update the value of a specific key for all objects without first loading each into memory. Similar approaches will be needed for the `remove_stale_data()` and `rename_object_data()` methods on CustomField as well. ### Use case This should result in a dramatic reduction in the time required to bulk update custom field data, particularly when many thousands of records are affected. ### Database changes N/A ### External dependencies N/A
adam added the status: acceptedtype: featurecomplexity: medium labels 2025-12-29 21:37:56 +01:00
adam closed this issue 2025-12-29 21:37:56 +01:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/netbox#10933