parent
df83277156
commit
58e8068958
|
|
@ -4,7 +4,7 @@ of the Python `post_save` handler formerly registered in netbox.denormalized.
|
|||
"""
|
||||
from django.db import migrations
|
||||
|
||||
from utilities.migration import cached_scope_triggers
|
||||
from utilities.migration import InstallDenormalizationTrigger
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
|
@ -15,4 +15,24 @@ class Migration(migrations.Migration):
|
|||
('dcim', '0238_ltree_paths'),
|
||||
]
|
||||
|
||||
operations = cached_scope_triggers('circuits_circuittermination')
|
||||
operations = [
|
||||
InstallDenormalizationTrigger(
|
||||
dependent_table='circuits_circuittermination',
|
||||
source_table='dcim_site',
|
||||
fk_column='_site_id',
|
||||
mappings={'_region_id': 'region_id', '_site_group_id': 'group_id'},
|
||||
),
|
||||
InstallDenormalizationTrigger(
|
||||
dependent_table='circuits_circuittermination',
|
||||
source_table='dcim_location',
|
||||
fk_column='_location_id',
|
||||
mappings={'_site_id': 'site_id'},
|
||||
related_mappings=(
|
||||
{
|
||||
'table': 'dcim_site',
|
||||
'source_fk': 'site_id',
|
||||
'mappings': {'_region_id': 'region_id', '_site_group_id': 'group_id'},
|
||||
},
|
||||
),
|
||||
),
|
||||
]
|
||||
|
|
|
|||
|
|
@ -34,9 +34,7 @@ from .utils import create_cablepaths, rebuild_paths
|
|||
def handle_location_site_change(instance, created, **kwargs):
|
||||
"""
|
||||
Cascade a Location's Site assignment down to the Racks, Devices, and PowerPanels it contains
|
||||
(and to descendant Locations). The denormalized cache columns on cable terminations and device
|
||||
components are maintained by PostgreSQL triggers, which fire on these Site/Location/Rack/Device
|
||||
column writes.
|
||||
(and to descendant Locations).
|
||||
"""
|
||||
if not created:
|
||||
instance.get_descendants().update(site=instance.site)
|
||||
|
|
@ -49,8 +47,7 @@ def handle_location_site_change(instance, created, **kwargs):
|
|||
@receiver(post_save, sender=Rack)
|
||||
def handle_rack_site_change(instance, created, **kwargs):
|
||||
"""
|
||||
Cascade a Rack's Site/Location assignment down to the Devices it contains. The denormalized cache
|
||||
columns on those devices' components are maintained by PostgreSQL triggers.
|
||||
Cascade a Rack's Site/Location assignment down to the Devices it contains.
|
||||
"""
|
||||
if not created:
|
||||
Device.objects.filter(rack=instance).update(site=instance.site, location=instance.location)
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ Python `post_save` handler formerly registered in netbox.denormalized (and dcim.
|
|||
"""
|
||||
from django.db import migrations
|
||||
|
||||
from utilities.migration import cached_scope_triggers
|
||||
from utilities.migration import InstallDenormalizationTrigger
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
|
@ -15,4 +15,24 @@ class Migration(migrations.Migration):
|
|||
('dcim', '0238_ltree_paths'),
|
||||
]
|
||||
|
||||
operations = cached_scope_triggers('ipam_prefix')
|
||||
operations = [
|
||||
InstallDenormalizationTrigger(
|
||||
dependent_table='ipam_prefix',
|
||||
source_table='dcim_site',
|
||||
fk_column='_site_id',
|
||||
mappings={'_region_id': 'region_id', '_site_group_id': 'group_id'},
|
||||
),
|
||||
InstallDenormalizationTrigger(
|
||||
dependent_table='ipam_prefix',
|
||||
source_table='dcim_location',
|
||||
fk_column='_location_id',
|
||||
mappings={'_site_id': 'site_id'},
|
||||
related_mappings=(
|
||||
{
|
||||
'table': 'dcim_site',
|
||||
'source_fk': 'site_id',
|
||||
'mappings': {'_region_id': 'region_id', '_site_group_id': 'group_id'},
|
||||
},
|
||||
),
|
||||
),
|
||||
]
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ from netbox.config import ConfigItem
|
|||
|
||||
__all__ = (
|
||||
'InstallDenormalizationTrigger',
|
||||
'cached_scope_triggers',
|
||||
'custom_deconstruct',
|
||||
)
|
||||
|
||||
|
|
@ -68,6 +67,15 @@ class InstallDenormalizationTrigger(migrations.operations.base.Operation):
|
|||
newly created source row has no dependents yet) and it does not recurse: the dependent tables carry no
|
||||
triggers of their own.
|
||||
|
||||
Example: refresh a CircuitTermination's cached region/sitegroup when its Site's region or group changes::
|
||||
|
||||
InstallDenormalizationTrigger(
|
||||
dependent_table='circuits_circuittermination',
|
||||
source_table='dcim_site',
|
||||
fk_column='_site_id',
|
||||
mappings={'_region_id': 'region_id', '_site_group_id': 'group_id'},
|
||||
)
|
||||
|
||||
Note: this is a row-level trigger, so a bulk source update of N rows fires it N times. A statement-level
|
||||
trigger with transition tables would batch this, but PostgreSQL forbids transition tables on a trigger
|
||||
with an `UPDATE OF <columns>` list, and dropping that column list would fire the trigger on every source
|
||||
|
|
@ -139,41 +147,3 @@ class InstallDenormalizationTrigger(migrations.operations.base.Operation):
|
|||
|
||||
def describe(self):
|
||||
return f'Install denormalization trigger on {self.source_table} updating {self.dependent_table}'
|
||||
|
||||
|
||||
# Site/region/site-group lookup shared by every CachedScopeMixin-style dependent (see cached_scope_triggers).
|
||||
SITE_SCOPE_RELATED_MAPPINGS = (
|
||||
{
|
||||
'table': 'dcim_site',
|
||||
'source_fk': 'site_id',
|
||||
'mappings': {'_region_id': 'region_id', '_site_group_id': 'group_id'},
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
def cached_scope_triggers(dependent_table):
|
||||
"""
|
||||
Return the Site + Location `InstallDenormalizationTrigger` pair for a dependent table carrying the
|
||||
standard cached-scope columns (_site/_location/_region/_site_group) — i.e. any CachedScopeMixin model
|
||||
(Prefix, Cluster, WirelessLAN) plus CircuitTermination, which share the same denormalization shape.
|
||||
|
||||
Region- and SiteGroup-scoped rows need no trigger: their cached FK is the scoped object itself and
|
||||
never changes underneath them. So two triggers fully cover the cache:
|
||||
- dcim_site: region/group changed -> refresh _region/_site_group on rows scoped to that site
|
||||
- dcim_location: site changed -> refresh _site (and the new site's region/group)
|
||||
"""
|
||||
return [
|
||||
InstallDenormalizationTrigger(
|
||||
dependent_table=dependent_table,
|
||||
source_table='dcim_site',
|
||||
fk_column='_site_id',
|
||||
mappings={'_region_id': 'region_id', '_site_group_id': 'group_id'},
|
||||
),
|
||||
InstallDenormalizationTrigger(
|
||||
dependent_table=dependent_table,
|
||||
source_table='dcim_location',
|
||||
fk_column='_location_id',
|
||||
mappings={'_site_id': 'site_id'},
|
||||
related_mappings=SITE_SCOPE_RELATED_MAPPINGS,
|
||||
),
|
||||
]
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ via PostgreSQL triggers instead of the Python `dcim.signals.sync_cached_scope_fi
|
|||
"""
|
||||
from django.db import migrations
|
||||
|
||||
from utilities.migration import cached_scope_triggers
|
||||
from utilities.migration import InstallDenormalizationTrigger
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
|
@ -15,4 +15,24 @@ class Migration(migrations.Migration):
|
|||
('dcim', '0238_ltree_paths'),
|
||||
]
|
||||
|
||||
operations = cached_scope_triggers('virtualization_cluster')
|
||||
operations = [
|
||||
InstallDenormalizationTrigger(
|
||||
dependent_table='virtualization_cluster',
|
||||
source_table='dcim_site',
|
||||
fk_column='_site_id',
|
||||
mappings={'_region_id': 'region_id', '_site_group_id': 'group_id'},
|
||||
),
|
||||
InstallDenormalizationTrigger(
|
||||
dependent_table='virtualization_cluster',
|
||||
source_table='dcim_location',
|
||||
fk_column='_location_id',
|
||||
mappings={'_site_id': 'site_id'},
|
||||
related_mappings=(
|
||||
{
|
||||
'table': 'dcim_site',
|
||||
'source_fk': 'site_id',
|
||||
'mappings': {'_region_id': 'region_id', '_site_group_id': 'group_id'},
|
||||
},
|
||||
),
|
||||
),
|
||||
]
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ handler.
|
|||
"""
|
||||
from django.db import migrations
|
||||
|
||||
from utilities.migration import cached_scope_triggers
|
||||
from utilities.migration import InstallDenormalizationTrigger
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
|
@ -16,4 +16,24 @@ class Migration(migrations.Migration):
|
|||
('dcim', '0238_ltree_paths'),
|
||||
]
|
||||
|
||||
operations = cached_scope_triggers('wireless_wirelesslan')
|
||||
operations = [
|
||||
InstallDenormalizationTrigger(
|
||||
dependent_table='wireless_wirelesslan',
|
||||
source_table='dcim_site',
|
||||
fk_column='_site_id',
|
||||
mappings={'_region_id': 'region_id', '_site_group_id': 'group_id'},
|
||||
),
|
||||
InstallDenormalizationTrigger(
|
||||
dependent_table='wireless_wirelesslan',
|
||||
source_table='dcim_location',
|
||||
fk_column='_location_id',
|
||||
mappings={'_site_id': 'site_id'},
|
||||
related_mappings=(
|
||||
{
|
||||
'table': 'dcim_site',
|
||||
'source_fk': 'site_id',
|
||||
'mappings': {'_region_id': 'region_id', '_site_group_id': 'group_id'},
|
||||
},
|
||||
),
|
||||
),
|
||||
]
|
||||
|
|
|
|||
Loading…
Reference in New Issue