Avoid unnecessary queries in Cable.from_db #3745

Closed
opened 2025-12-29 18:30:53 +01:00 by adam · 1 comment
Owner

Originally created by @steffann on GitHub (Jun 4, 2020).

Originally assigned to: @steffann on GitHub.

Proposed Changes

Change the code in https://github.com/netbox-community/netbox/blob/develop/netbox/dcim/models/init.py#L2118-L2121 where a copy is made of the termination points. I suggest to change it to:

instance._orig_termination_a_type_id = instance.termination_a_type_id
instance._orig_termination_a_id = instance.termination_a_id
instance._orig_termination_b_type_id = instance.termination_b_type_id
instance._orig_termination_b_id = instance.termination_b_id

And change the corresponding usage to:

if (
    self.termination_a_type_id != self._orig_termination_a_type_id or
    self.termination_a_id != self._orig_termination_a_id
):
    raise ValidationError({
        'termination_a': err_msg
    })
if (
    self.termination_b_type_id != self._orig_termination_b_type_id or
    self.termination_b_id != self._orig_termination_b_id
):
    raise ValidationError({
        'termination_b': err_msg
    })

Justification

Reading the …_type properties triggers database queries to retrieve a ContentType object, which is later only used in a comparison. Storing the …_type_id is sufficient for that and avoids the queries.

Originally created by @steffann on GitHub (Jun 4, 2020). Originally assigned to: @steffann on GitHub. ### Proposed Changes Change the code in https://github.com/netbox-community/netbox/blob/develop/netbox/dcim/models/__init__.py#L2118-L2121 where a copy is made of the termination points. I suggest to change it to: ``` instance._orig_termination_a_type_id = instance.termination_a_type_id instance._orig_termination_a_id = instance.termination_a_id instance._orig_termination_b_type_id = instance.termination_b_type_id instance._orig_termination_b_id = instance.termination_b_id ``` And change the corresponding usage to: ``` if ( self.termination_a_type_id != self._orig_termination_a_type_id or self.termination_a_id != self._orig_termination_a_id ): raise ValidationError({ 'termination_a': err_msg }) if ( self.termination_b_type_id != self._orig_termination_b_type_id or self.termination_b_id != self._orig_termination_b_id ): raise ValidationError({ 'termination_b': err_msg }) ``` ### Justification Reading the `…_type` properties triggers database queries to retrieve a `ContentType` object, which is later only used in a comparison. Storing the `…_type_id` is sufficient for that and avoids the queries.
adam added the status: acceptedtype: housekeeping labels 2025-12-29 18:30:53 +01:00
adam closed this issue 2025-12-29 18:30:54 +01:00
Author
Owner

@steffann commented on GitHub (Jun 4, 2020):

I noticed this behaviour when looking at the debug toolbar:

Schermafbeelding 2020-06-04 om 16 21 47

I tested with prefetch_related, but that doesn't affect the behaviour. It fetches the cables in one query, which is then followed by all the queries for the content types, one by one.

@steffann commented on GitHub (Jun 4, 2020): I noticed this behaviour when looking at the debug toolbar: <img width="1191" alt="Schermafbeelding 2020-06-04 om 16 21 47" src="https://user-images.githubusercontent.com/509689/83769357-064dad00-a680-11ea-9746-4bb29cb5c373.png"> I tested with `prefetch_related`, but that doesn't affect the behaviour. It fetches the cables in one query, which is then followed by all the queries for the content types, one by one.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/netbox#3745