opencivicdata / python-opencivicdata

python utilities for Open Civic Data

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Error when computing diff to merge orgs

gordonje opened this issue · comments

Here is a stripped down example:

from opencivicdata.core.models import Organization
from opencivicdata import merge

org1 = Organization.objects.create(name='org1')
org2 = Organization.objects.create(name='org2')

merge.merge(org1, org2)

Yield this error:

~/.virtualenvs/django-calaccess-processed-data-py3/src/python-opencivicdata/opencivicdata/merge.py in merge(obj1, obj2)
    126
    127 def merge(obj1, obj2):
--> 128     diff = compute_diff(obj1, obj2)
    129     apply_diff(obj1, obj2, diff)
    130

~/.virtualenvs/django-calaccess-processed-data-py3/src/python-opencivicdata/opencivicdata/merge.py in compute_diff(obj1, obj2)
     46             })
     47         else:
---> 48             related_name = field.get_accessor_name()
     49             piece_one = list(getattr(obj1, related_name).all())
     50             piece_two = list(getattr(obj2, related_name).all())

AttributeError: 'ForeignKey' object has no attribute 'get_accessor_name'

Looks like there are two fields missing the get_accessor_name method:

related_fields = [f for f in org1._meta.get_fields() if f.is_relation]
for field in related_fields:
    if not getattr(field, "get_accessor_name", None):
        print(field)

Yields:

core.Organization.parent
core.Organization.jurisdiction

looks like merge.py is mainly focused on merging two people. here is some effort to merge objects other than person objects.

            try:
                related_name = field.get_accessor_name()
                piece_one = list(getattr(obj1, related_name).all())
                piece_two = list(getattr(obj2, related_name).all())
            except AttributeError:
                query1 = {'{}'.format(field.related_query_name()): obj1}
                query2 = {'{}'.format(field.related_query_name()): obj2}
                piece_one = list(field.related_model.objects.filter(**query1))
                piece_two = list(field.related_model.objects.filter(**query2))

#120 removes these unless anyone objects