BookDataModel.merge_into: return and log absorbed fields

This commit is contained in:
Bart Schuurmans 2024-03-02 11:34:20 +01:00
parent e04cd79ff8
commit 7066e2815b
3 changed files with 13 additions and 6 deletions

View file

@ -30,7 +30,8 @@ def dedupe_model(model):
print(f"merging into {canonical.remote_id} based on {field.name} {value}:") print(f"merging into {canonical.remote_id} based on {field.name} {value}:")
for obj in objs[1:]: for obj in objs[1:]:
print(f"- {obj.remote_id}") print(f"- {obj.remote_id}")
obj.merge_into(canonical) absorbed_fields = obj.merge_into(canonical)
print(f" absorbed fields: {absorbed_fields}")
class Command(BaseCommand): class Command(BaseCommand):

View file

@ -25,4 +25,6 @@ class MergeCommand(BaseCommand):
print("other book doesnt exist!") print("other book doesnt exist!")
return return
other.merge_into(canonical) absorbed_fields = other.merge_into(canonical)
print(f"{other.remote_id} has been merged into {canonical.remote_id}")
print(f"absorbed fields: {absorbed_fields}")

View file

@ -2,7 +2,7 @@
from itertools import chain from itertools import chain
import re import re
from typing import Any from typing import Any, Dict
from typing_extensions import Self from typing_extensions import Self
from django.contrib.postgres.search import SearchVectorField from django.contrib.postgres.search import SearchVectorField
@ -110,12 +110,12 @@ class BookDataModel(ObjectMixin, BookWyrmModel):
"""only send book data updates to other bookwyrm instances""" """only send book data updates to other bookwyrm instances"""
super().broadcast(activity, sender, software=software, **kwargs) super().broadcast(activity, sender, software=software, **kwargs)
def merge_into(self, canonical: Self) -> None: def merge_into(self, canonical: Self) -> Dict[str, Any]:
"""merge this entity into another entity""" """merge this entity into another entity"""
if canonical.id == self.id: if canonical.id == self.id:
raise ValueError(f"Cannot merge {self} into itself") raise ValueError(f"Cannot merge {self} into itself")
canonical.absorb_data_from(self) absorbed_fields = canonical.absorb_data_from(self)
canonical.save() canonical.save()
self.merged_model.objects.create(deleted_id=self.id, merged_into=canonical) self.merged_model.objects.create(deleted_id=self.id, merged_into=canonical)
@ -147,9 +147,11 @@ class BookDataModel(ObjectMixin, BookWyrmModel):
getattr(related_obj, related_field).remove(self) getattr(related_obj, related_field).remove(self)
self.delete() self.delete()
return absorbed_fields
def absorb_data_from(self, other: Self) -> None: def absorb_data_from(self, other: Self) -> Dict[str, Any]:
"""fill empty fields with values from another entity""" """fill empty fields with values from another entity"""
absorbed_fields = {}
for data_field in self._meta.get_fields(): for data_field in self._meta.get_fields():
if not hasattr(data_field, "activitypub_field"): if not hasattr(data_field, "activitypub_field"):
continue continue
@ -158,6 +160,8 @@ class BookDataModel(ObjectMixin, BookWyrmModel):
continue continue
if not getattr(self, data_field.name): if not getattr(self, data_field.name):
setattr(self, data_field.name, data_value) setattr(self, data_field.name, data_value)
absorbed_fields[data_field.name] = data_value
return absorbed_fields
class MergedBookDataModel(models.Model): class MergedBookDataModel(models.Model):