13745 update migrations to use subquery update

This commit is contained in:
Arthur 2023-09-12 13:14:15 -07:00
parent f3cc8d5422
commit 1c6c642bd9

View File

@ -1,48 +1,41 @@
from django.db import migrations from django.db import migrations
from django.db.models import Count from django.db.models import Count
from django.db.models import Count, OuterRef, Subquery
import utilities.fields 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): def recalculate_devicetype_template_counts(apps, schema_editor):
DeviceType = apps.get_model("dcim", "DeviceType") 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: update_counts(DeviceType, 'console_port_template_count', 'consoleporttemplates')
devicetype.console_port_template_count = devicetype._console_port_template_count update_counts(DeviceType, 'console_server_port_template_count', 'consoleserverporttemplates')
devicetype.console_server_port_template_count = devicetype._console_server_port_template_count update_counts(DeviceType, 'power_port_template_count', 'powerporttemplates')
devicetype.power_port_template_count = devicetype._power_port_template_count update_counts(DeviceType, 'power_outlet_template_count', 'poweroutlettemplates')
devicetype.power_outlet_template_count = devicetype._power_outlet_template_count update_counts(DeviceType, 'interface_template_count', 'interfacetemplates')
devicetype.interface_template_count = devicetype._interface_template_count update_counts(DeviceType, 'front_port_template_count', 'frontporttemplates')
devicetype.front_port_template_count = devicetype._front_port_template_count update_counts(DeviceType, 'rear_port_template_count', 'rearporttemplates')
devicetype.rear_port_template_count = devicetype._rear_port_template_count update_counts(DeviceType, 'device_bay_template_count', 'devicebaytemplates')
devicetype.device_bay_template_count = devicetype._device_bay_template_count update_counts(DeviceType, 'module_bay_template_count', 'modulebaytemplates')
devicetype.module_bay_template_count = devicetype._module_bay_template_count update_counts(DeviceType, 'inventory_item_template_count', 'inventoryitemtemplates')
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)
class Migration(migrations.Migration): class Migration(migrations.Migration):