Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closes #18980: Optimize update of object data when adding/removing custom fields #18983

Merged
merged 3 commits into from
Mar 24, 2025

Conversation

jeremystretch
Copy link
Member

@jeremystretch jeremystretch commented Mar 21, 2025

Fixes: #18980

  • populate_initial_data() now uses the PostgreSQL-native jsonb_set() function to set initial values on objects when creating a custom field
  • remove_stale_data() now uses native JSON mutation to remove the keys for deleted custom fields
  • rename_object_data() has likewise been optimized to rename custom field keys in object data using jsonb_set()

A quick test using a REST API call adding a custom field to ~11,000 interfaces took 0.543s with this change versus 5.556s in main.

@jeremystretch jeremystretch changed the title Closes #19890: Optimize update of object data when adding/removing custom fields Closes #18980: Optimize update of object data when adding/removing custom fields Mar 21, 2025
@jeremystretch jeremystretch requested review from a team and jnovinger and removed request for a team March 24, 2025 13:47
@jeremystretch jeremystretch marked this pull request as ready for review March 24, 2025 13:47
Copy link
Member

@jnovinger jnovinger left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just had a couple of quick questions.

value,
function='jsonb_set'
)
)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Previously, we weren't updating instances that already had a value for the self.name path in the custom field data field (I think) and only setting it on those that did not.

But now we're just flat out setting the default value on all records (either adding or updating, per jsonb_set docs), is that right? I think this is safe to do since this is only running as a result of adding new custom field. Is that the reasoning or is there something else I'm missing?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IIRC the exclusion filter was left over from an earlier implementation of custom fields and is no longer needed. An argument could be made for retaining it, however it's cleaner IMO to overwrite any data that happens to exist (somehow) when adding a new custom field on the model, because that's what I'd expect to happen as a user.

model.objects.bulk_update(instances, ['custom_field_data'], batch_size=100)
ct.model_class().objects.update(
custom_field_data=F('custom_field_data') - self.name
)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Previously there was a check here (but oddly not in the other modified methods) to make sure the result of ct.model_class() wasn't falsy (I assume None, which I've seen locally once or twice).

Is the feeling that it's safe to assume that we'll never try to call None.objects?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch. I suspect it might be there to elegantly handle the case where a plugin model has been removed. I'm going to restore the check.

@jeremystretch jeremystretch requested a review from jnovinger March 24, 2025 16:46
@jnovinger jnovinger merged commit af5a600 into main Mar 24, 2025
6 checks passed
@jnovinger jnovinger deleted the 18980-custom-field-bulk-updates branch March 24, 2025 17:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Optimize bulk updates of custom field values when custom fields are added/removed
2 participants