Browse Source

#21488 - Replace MPTT wtih PostgreSQL Ltree

Arthur 1 day ago
parent
commit
162ab548e6

+ 0 - 17
netbox/dcim/migrations/0234_enable_ltree_extension.py

@@ -1,17 +0,0 @@
-from django.contrib.postgres.operations import CreateExtension
-from django.db import migrations
-
-
-class Migration(migrations.Migration):
-    """
-    Enable the PostgreSQL ltree extension. Required by the next migration which
-    adds the `path` column on hierarchical models.
-    """
-
-    dependencies = [
-        ('dcim', '0233_device_render_config_permission'),
-    ]
-
-    operations = [
-        CreateExtension('ltree'),
-    ]

+ 14 - 10
netbox/dcim/migrations/0235_ltree_paths.py → netbox/dcim/migrations/0234_ltree_paths.py

@@ -4,16 +4,17 @@ Replace django-mptt with PostgreSQL ltree for dcim's hierarchical models.
 For each of (Region, SiteGroup, Location, DeviceRole, Platform, ModuleBay,
 InventoryItem, InventoryItemTemplate) this migration:
 
-1. Adds a nullable `path` LTreeField.
-2. Installs per-table BEFORE-INSERT/UPDATE-OF-parent_id and AFTER-UPDATE-OF-path
-   triggers so concurrent writes during the long-running data step get correct
-   paths.
-3. Populates paths for existing rows via a single recursive CTE per table.
-4. Tightens `path` to NOT NULL.
-5. Drops the legacy MPTT columns (lft, rght, tree_id, level).
-6. Adds a GiST index on the `path` column for efficient `@>` / `<@` lookups.
+1. Enables the PostgreSQL ltree extension (idempotent).
+2. Adds a nullable `path` LTreeField.
+3. Installs per-table BEFORE-INSERT/UPDATE-OF-parent_id and AFTER-UPDATE-OF-(parent_id, path)
+   triggers so concurrent writes during the long-running data step get correct paths.
+4. Populates paths for existing rows via a single recursive CTE per table.
+5. Tightens `path` to NOT NULL.
+6. Drops the legacy MPTT columns (lft, rght, tree_id, level).
+7. Adds a GiST index on the `path` column for efficient `@>` / `<@` lookups.
 """
 from django.contrib.postgres.indexes import GistIndex
+from django.contrib.postgres.operations import CreateExtension
 from django.db import migrations
 
 import netbox.models.ltree
@@ -56,11 +57,14 @@ UPDATE "{table}" SET path = t.path FROM t WHERE "{table}".id = t.id;
 class Migration(migrations.Migration):
 
     dependencies = [
-        ('dcim', '0234_enable_ltree_extension'),
+        ('dcim', '0233_device_render_config_permission'),
     ]
 
     operations = [
-        # 1. Add nullable path column
+        # 1. Enable the ltree extension (idempotent — CreateExtension emits IF NOT EXISTS)
+        CreateExtension('ltree'),
+
+        # 2. Add nullable path column
         *[
             migrations.AddField(
                 model_name=m,

+ 0 - 17
netbox/tenancy/migrations/0025_enable_ltree_extension.py

@@ -1,17 +0,0 @@
-from django.contrib.postgres.operations import CreateExtension
-from django.db import migrations
-
-
-class Migration(migrations.Migration):
-    """
-    Enable the PostgreSQL ltree extension. Idempotent across apps; only one
-    CreateExtension('ltree') needs to succeed during a single migrate run.
-    """
-
-    dependencies = [
-        ('tenancy', '0024_default_ordering_indexes'),
-    ]
-
-    operations = [
-        CreateExtension('ltree'),
-    ]

+ 5 - 1
netbox/tenancy/migrations/0026_ltree_paths.py → netbox/tenancy/migrations/0025_ltree_paths.py

@@ -1,5 +1,6 @@
 """Replace django-mptt with PostgreSQL ltree for tenancy's hierarchical models."""
 from django.contrib.postgres.indexes import GistIndex
+from django.contrib.postgres.operations import CreateExtension
 from django.db import migrations
 
 import netbox.models.ltree
@@ -28,10 +29,13 @@ UPDATE "{table}" SET path = t.path FROM t WHERE "{table}".id = t.id;
 class Migration(migrations.Migration):
 
     dependencies = [
-        ('tenancy', '0025_enable_ltree_extension'),
+        ('tenancy', '0024_default_ordering_indexes'),
     ]
 
     operations = [
+        # Enable the ltree extension (idempotent — CreateExtension emits IF NOT EXISTS)
+        CreateExtension('ltree'),
+
         *[
             migrations.AddField(
                 model_name=m,

+ 0 - 17
netbox/wireless/migrations/0020_enable_ltree_extension.py

@@ -1,17 +0,0 @@
-from django.contrib.postgres.operations import CreateExtension
-from django.db import migrations
-
-
-class Migration(migrations.Migration):
-    """
-    Enable the PostgreSQL ltree extension. Idempotent across apps; only one
-    CreateExtension('ltree') needs to succeed during a single migrate run.
-    """
-
-    dependencies = [
-        ('wireless', '0019_default_ordering_indexes'),
-    ]
-
-    operations = [
-        CreateExtension('ltree'),
-    ]

+ 5 - 1
netbox/wireless/migrations/0021_ltree_paths.py → netbox/wireless/migrations/0020_ltree_paths.py

@@ -1,5 +1,6 @@
 """Replace django-mptt with PostgreSQL ltree for wireless's hierarchical models."""
 from django.contrib.postgres.indexes import GistIndex
+from django.contrib.postgres.operations import CreateExtension
 from django.db import migrations
 
 import netbox.models.ltree
@@ -13,10 +14,13 @@ LEGACY_FIELDS = ('lft', 'rght', 'tree_id', 'level')
 class Migration(migrations.Migration):
 
     dependencies = [
-        ('wireless', '0020_enable_ltree_extension'),
+        ('wireless', '0019_default_ordering_indexes'),
     ]
 
     operations = [
+        # Enable the ltree extension (idempotent — CreateExtension emits IF NOT EXISTS)
+        CreateExtension('ltree'),
+
         migrations.AddField(
             model_name=MODEL,
             name='path',