fix: reconcile component mappings by natural key

This commit is contained in:
2026-08-05 14:05:40 +02:00
parent f22276d68d
commit 8107e152d2
6 changed files with 83 additions and 9 deletions
+1 -1
View File
@@ -7,7 +7,7 @@ class NetBoxExportConfig(PluginConfig):
name = "netbox_export"
verbose_name = "NetBox-Export"
description = "Portable ZIP export and import for tenants and locations"
version = "0.3.6"
version = "0.3.7"
author = "NetBox Export contributors"
base_url = "netbox-export"
min_version = "4.6.0"
+1 -1
View File
@@ -39,7 +39,7 @@ def export_scope(
"created_at": datetime.now(UTC).isoformat(),
"source_instance": str(InstanceIdentity.local_id()),
"source_netbox_version": getattr(getattr(settings, "RELEASE", None), "version", "4.6"),
"plugin_version": "0.3.6",
"plugin_version": "0.3.7",
"scope": {
"type": scope_type,
"source_pk": str(scope_id),
+12 -5
View File
@@ -38,6 +38,8 @@ EXPLICIT_IDENTITIES = {
"dcim.consoleserverport": ("device", "name"),
"dcim.powerport": ("device", "name"),
"dcim.poweroutlet": ("device", "name"),
"dcim.frontport": ("device", "name"),
"dcim.rearport": ("device", "name"),
"dcim.devicebay": ("device", "name"),
"dcim.modulebay": ("device", "name"),
"dcim.inventoryitem": ("device", "parent", "name"),
@@ -191,19 +193,24 @@ def _mapped_object(source_instance: uuid.UUID, record: dict, model):
def _find_existing(source_instance, model, record, resolver):
mapped = _mapped_object(source_instance, record, model)
if mapped is not None:
return mapped
lookup = _identity_lookup(model, record, resolver)
if not lookup:
return None
return mapped
try:
return model._default_manager.get(**lookup)
natural = model._default_manager.get(**lookup)
except model.DoesNotExist:
return None
return mapped
except model.MultipleObjectsReturned as exc:
raise ImportConflictError(
f"Mehrere Zielobjekte passen auf {record['model']} mit {lookup}."
) from exc
if mapped is not None and mapped.pk != natural.pk:
resolver.warn(
("mapping-rebound", record["id"]),
f"Gespeicherte Zuordnung für {record['id']} wurde von Ziel-ID {mapped.pk} auf "
f"Ziel-ID {natural.pk} korrigiert, da der Fachschlüssel {lookup} bereits existiert.",
)
return natural
def _write_mapping(source_instance, record, obj):