From 1c6c642bd96b28f63510e3bb5b979709836d2a0b Mon Sep 17 00:00:00 2001 From: Arthur Date: Tue, 12 Sep 2023 13:14:15 -0700 Subject: [PATCH] 13745 update migrations to use subquery update --- .../0177_devicetype_component_counters.py | 65 +++++++++---------- 1 file changed, 29 insertions(+), 36 deletions(-) diff --git a/netbox/dcim/migrations/0177_devicetype_component_counters.py b/netbox/dcim/migrations/0177_devicetype_component_counters.py index a8e37e5ee..8afb3af5c 100644 --- a/netbox/dcim/migrations/0177_devicetype_component_counters.py +++ b/netbox/dcim/migrations/0177_devicetype_component_counters.py @@ -1,48 +1,41 @@ from django.db import migrations from django.db.models import Count +from django.db.models import Count, OuterRef, Subquery import utilities.fields +def update_counts(model, field_name, related_query): + """ + Perform a bulk update for the given model and counter field. For example, + + update_counts(Device, '_interface_count', 'interfaces') + + will effectively set + + Device.objects.update(_interface_count=Count('interfaces')) + """ + subquery = Subquery( + model.objects.filter(pk=OuterRef('pk')).annotate(_count=Count(related_query)).values('_count') + ) + return model.objects.update(**{ + field_name: subquery + }) + + def recalculate_devicetype_template_counts(apps, schema_editor): DeviceType = apps.get_model("dcim", "DeviceType") - device_types = DeviceType.objects.all().annotate( - _console_port_template_count=Count('consoleporttemplates', distinct=True), - _console_server_port_template_count=Count('consoleserverporttemplates', distinct=True), - _power_port_template_count=Count('powerporttemplates', distinct=True), - _power_outlet_template_count=Count('poweroutlettemplates', distinct=True), - _interface_template_count=Count('interfacetemplates', distinct=True), - _front_port_template_count=Count('frontporttemplates', distinct=True), - _rear_port_template_count=Count('rearporttemplates', distinct=True), - _device_bay_template_count=Count('devicebaytemplates', distinct=True), - _module_bay_template_count=Count('modulebaytemplates', distinct=True), - _inventory_item_template_count=Count('inventoryitemtemplates', distinct=True), - ) - for devicetype in device_types: - devicetype.console_port_template_count = devicetype._console_port_template_count - devicetype.console_server_port_template_count = devicetype._console_server_port_template_count - devicetype.power_port_template_count = devicetype._power_port_template_count - devicetype.power_outlet_template_count = devicetype._power_outlet_template_count - devicetype.interface_template_count = devicetype._interface_template_count - devicetype.front_port_template_count = devicetype._front_port_template_count - devicetype.rear_port_template_count = devicetype._rear_port_template_count - devicetype.device_bay_template_count = devicetype._device_bay_template_count - devicetype.module_bay_template_count = devicetype._module_bay_template_count - devicetype.inventory_item_template_count = devicetype._inventory_item_template_count - - DeviceType.objects.bulk_update(device_types, [ - 'console_port_template_count', - 'console_server_port_template_count', - 'power_port_template_count', - 'power_outlet_template_count', - 'interface_template_count', - 'front_port_template_count', - 'rear_port_template_count', - 'device_bay_template_count', - 'module_bay_template_count', - 'inventory_item_template_count', - ], batch_size=100) + update_counts(DeviceType, 'console_port_template_count', 'consoleporttemplates') + update_counts(DeviceType, 'console_server_port_template_count', 'consoleserverporttemplates') + update_counts(DeviceType, 'power_port_template_count', 'powerporttemplates') + update_counts(DeviceType, 'power_outlet_template_count', 'poweroutlettemplates') + update_counts(DeviceType, 'interface_template_count', 'interfacetemplates') + update_counts(DeviceType, 'front_port_template_count', 'frontporttemplates') + update_counts(DeviceType, 'rear_port_template_count', 'rearporttemplates') + update_counts(DeviceType, 'device_bay_template_count', 'devicebaytemplates') + update_counts(DeviceType, 'module_bay_template_count', 'modulebaytemplates') + update_counts(DeviceType, 'inventory_item_template_count', 'inventoryitemtemplates') class Migration(migrations.Migration):