error on 1:1 clash

This commit is contained in:
James Turk 2015-05-28 16:28:21 -04:00
parent 8d4bab0563
commit 750061ebd6
2 changed files with 28 additions and 7 deletions

View File

@ -1,5 +1,20 @@
from django.core.exceptions import ObjectDoesNotExist
def merge(from_obj, to_obj):
class MergeException(Exception):
pass
class OneToOneConflict(MergeException):
pass
ERROR = 0
KEEP = 1
UPDATE = 2
def merge(from_obj, to_obj, one_to_one_conflict=ERROR):
if not isinstance(from_obj, type(to_obj)):
raise ValueError("both objects must be of the same type")
@ -17,17 +32,17 @@ def merge(from_obj, to_obj):
try:
field = getattr(from_obj, accessor_name)
try:
getattr(to_obj, accessor_name)
except Exception as e:
to_obj_field = getattr(to_obj, accessor_name)
raise OneToOneConflict("both fields have an attribute set for {}".format(accessor_name))
except ObjectDoesNotExist:
# doesn't exist, safe to overwrite
setattr(field, varname, to_obj)
field.save()
except Exception as e:
except ObjectDoesNotExist:
# from_obj one to one isn't set, skip
pass
else:
import pdb; pdb.set_trace()
raise Exception('unknown code path')
raise NotImplementedError('unexpected relation type, please file a bug')
for related in from_obj._meta.get_all_related_many_to_many_objects():
accessor_name = related.get_accessor_name()

View File

@ -1,6 +1,6 @@
from django.test import TestCase
from .models import Person, Number, SSN, Group
from fkreplace import merge
from fkreplace import merge, OneToOneConflict
class MergeTests(TestCase):
def setUp(self):
@ -44,6 +44,12 @@ class MergeTests(TestCase):
assert SSN.objects.count() == 1
# TODO: test one2one when there's a conflict
def test_one2one_conflict(self):
SSN.objects.create(person=self.a, number='1')
SSN.objects.create(person=self.b, number='1')
with self.assertRaises(OneToOneConflict):
merge(self.a, self.b)
def test_many2many_simple(self):
self.g.people.add(self.a)