Skip to content

Commit 6f9f8b8

Browse files
snaseljHanlinMiao
andauthored
Bump diffsync v2.1 (#219)
* bump: DiffSync `v2.1` * chore: Build fixtures * changelog --------- Co-authored-by: HanlinMiao <hanlin980505@gmail.com>
1 parent 3081b39 commit 6f9f8b8

File tree

6 files changed

+294
-170
lines changed

6 files changed

+294
-170
lines changed

changes/219.dependencies

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Bumped diffsync to `v2.1`.
2+
Bumped pydantic to `v2.11.5`.

nautobot_netbox_importer/generator/base.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
from uuid import UUID, uuid5
88

99
from dateutil import parser as datetime_parser
10-
from diffsync import DiffSync
10+
from diffsync import Adapter
1111
from diffsync.store.local import LocalStore
1212
from django.conf import settings
1313
from django.core.exceptions import FieldDoesNotExist as DjangoFieldDoesNotExist
@@ -223,7 +223,7 @@ def normalize_datetime(value: Any) -> Optional[datetime.datetime]:
223223
return value.astimezone(datetime.timezone.utc)
224224

225225

226-
class BaseAdapter(DiffSync):
226+
class BaseAdapter(Adapter):
227227
"""Base class for Generator Adapters."""
228228

229229
def __init__(self, *args, **kwargs):

nautobot_netbox_importer/generator/nautobot.py

Lines changed: 36 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,17 @@
22

33
from typing import Any, Dict, Iterable, List, Mapping, MutableMapping, Optional, Set, Type
44

5-
from diffsync import DiffSync, DiffSyncModel
5+
from diffsync import Adapter, DiffSyncModel
66
from diffsync.enum import DiffSyncModelFlags
77
from django.contrib.contenttypes.models import ContentType
88
from django.db.models import Max
99
from django.db.transaction import atomic
1010
from nautobot.core.utils.lookup import get_model_from_name
1111
from nautobot.extras.models import Tag
12+
from pydantic import Field, create_model
1213

1314
from nautobot_netbox_importer.base import FieldName, RecordData, logger
14-
from nautobot_netbox_importer.summary import (
15-
ImporterIssue,
16-
ImportSummary,
17-
NautobotModelStats,
18-
NautobotModelSummary,
19-
get_issue_tag,
20-
)
21-
22-
from .base import (
15+
from nautobot_netbox_importer.generator.base import (
2316
AUTO_ADD_FIELDS,
2417
EMPTY_VALUES,
2518
INTERNAL_AUTO_INC_TYPES,
@@ -34,14 +27,20 @@
3427
InternalFieldType,
3528
NautobotBaseModel,
3629
NautobotBaseModelType,
37-
PydanticField,
3830
StrToInternalFieldType,
3931
Uid,
4032
get_nautobot_field_and_type,
4133
normalize_datetime,
4234
source_pk_to_uuid,
4335
)
44-
from .exceptions import NautobotModelNotFound
36+
from nautobot_netbox_importer.generator.exceptions import NautobotModelNotFound
37+
from nautobot_netbox_importer.summary import (
38+
ImporterIssue,
39+
ImportSummary,
40+
NautobotModelStats,
41+
NautobotModelSummary,
42+
get_issue_tag,
43+
)
4544

4645
# Helper to determine the import order of models.
4746
# Due to dependencies among Nautobot models, certain models must be imported first to ensure successful `instance.save()` calls without errors.
@@ -265,48 +264,50 @@ def diffsync_class(self) -> Type["DiffSyncBaseModel"]:
265264
if self.disabled:
266265
raise RuntimeError("Cannot create importer for disabled model")
267266

268-
annotations = {}
269267
attributes = []
268+
field_definitions = {}
270269
identifiers = []
271270

272-
class_definition = {
273-
"__annotations__": annotations,
274-
"_attributes": attributes,
275-
"_identifiers": identifiers,
276-
"_modelname": self.content_type.replace(".", "_"),
277-
"_wrapper": self,
278-
}
279-
280-
annotations[self.pk_field.name] = INTERNAL_TYPE_TO_ANNOTATION[self.pk_field.internal_type]
271+
pk_type = INTERNAL_TYPE_TO_ANNOTATION[self.pk_field.internal_type]
272+
field_definitions[self.pk_field.name] = (pk_type, Field())
281273
identifiers.append(self.pk_field.name)
282-
class_definition[self.pk_field.name] = PydanticField()
283274

284275
for field in self.fields.values():
285276
if field.name in identifiers or not field.can_import:
286277
continue
287278

288279
if field.is_reference:
289280
related_type = StrToInternalFieldType[field.related_meta.pk.get_internal_type()] # type: ignore
290-
annotation = INTERNAL_TYPE_TO_ANNOTATION[related_type]
281+
field_type = INTERNAL_TYPE_TO_ANNOTATION[related_type]
291282
if field.internal_type == InternalFieldType.MANY_TO_MANY_FIELD:
292-
annotation = Set[annotation]
283+
field_type = Set[field_type]
293284
else:
294-
annotation = INTERNAL_TYPE_TO_ANNOTATION[field.internal_type]
285+
field_type = INTERNAL_TYPE_TO_ANNOTATION[field.internal_type]
286+
287+
field_type = Optional[field_type]
295288

289+
field_definitions[field.name] = (field_type, Field(default=None))
296290
attributes.append(field.name)
297-
if not field.required:
298-
annotation = Optional[annotation]
299-
annotations[field.name] = annotation
300-
class_definition[field.name] = PydanticField(default=None)
291+
292+
model_name = self.content_type.replace(".", "_")
301293

302294
try:
303-
result = type(class_definition["_modelname"], (DiffSyncBaseModel,), class_definition)
295+
result = create_model(model_name, __base__=DiffSyncBaseModel, **field_definitions)
296+
# pylint: disable=protected-access
297+
result._modelname = model_name
298+
# pylint: disable=protected-access
299+
result._attributes = tuple(attributes)
300+
# pylint: disable=protected-access
301+
result._identifiers = tuple(identifiers)
302+
# pylint: disable=protected-access
303+
result._wrapper = self
304+
304305
self._diffsync_class = result
305306
except Exception:
306-
logger.error("Failed to create DiffSync Model %s", class_definition, exc_info=True)
307+
logger.error("Failed to create DiffSync Model %s", field_definitions, exc_info=True)
307308
raise
308309

309-
logger.debug("Created DiffSync Model %s", class_definition)
310+
logger.debug("Created DiffSync result %s", field_definitions)
310311

311312
return result
312313

@@ -770,14 +771,14 @@ class DiffSyncBaseModel(DiffSyncModel):
770771
_wrapper: NautobotModelWrapper
771772

772773
@classmethod
773-
def create(cls, diffsync: DiffSync, ids: dict, attrs: dict) -> Optional["DiffSyncBaseModel"]:
774+
def create(cls, adapter: Adapter, ids: dict, attrs: dict) -> Optional["DiffSyncBaseModel"]:
774775
"""Create this model instance, both in Nautobot and in DiffSync."""
775776
wrapper = cls._wrapper
776777

777778
instance = None
778779
try:
779780
instance = wrapper.model(**wrapper.constructor_kwargs, **ids)
780-
result = super().create(diffsync, ids, attrs)
781+
result = super().create(adapter, ids, attrs)
781782
# pylint: disable=broad-exception-caught
782783
except Exception as error:
783784
wrapper.add_issue(

0 commit comments

Comments
 (0)