handle onetoone conflicts and deletes

This commit is contained in:
James Turk 2015-05-28 16:45:07 -04:00
parent 750061ebd6
commit bd01e38f35
2 changed files with 33 additions and 6 deletions

View File

@ -11,7 +11,7 @@ class OneToOneConflict(MergeException):
ERROR = 0
KEEP = 1
UPDATE = 2
DELETE = 2
def merge(from_obj, to_obj, one_to_one_conflict=ERROR):
@ -32,8 +32,18 @@ def merge(from_obj, to_obj, one_to_one_conflict=ERROR):
try:
field = getattr(from_obj, accessor_name)
try:
to_obj_field = getattr(to_obj, accessor_name)
raise OneToOneConflict("both fields have an attribute set for {}".format(accessor_name))
to_field = getattr(to_obj, accessor_name)
if one_to_one_conflict == KEEP:
pass # do nothing
elif one_to_one_conflict == DELETE:
# if null:
# setattr(to_field, varname, None)
# to_field.save()
to_field.delete()
setattr(field, varname, to_obj)
field.save()
else:
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)

View File

@ -1,6 +1,6 @@
from django.test import TestCase
from .models import Person, Number, SSN, Group
from fkreplace import merge, OneToOneConflict
from fkreplace import merge, OneToOneConflict, KEEP, DELETE
class MergeTests(TestCase):
def setUp(self):
@ -43,14 +43,31 @@ class MergeTests(TestCase):
assert Person.objects.get(pk=self.b.pk).ssn.number == '1'
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')
SSN.objects.create(person=self.b, number='2')
with self.assertRaises(OneToOneConflict):
merge(self.a, self.b)
def test_one2one_conflict_keep(self):
SSN.objects.create(person=self.a, number='1')
SSN.objects.create(person=self.b, number='2')
merge(self.a, self.b, KEEP)
assert Person.objects.get(pk=self.a.pk).ssn.number == '1'
assert Person.objects.get(pk=self.b.pk).ssn.number == '2'
def test_one2one_conflict_delete(self):
SSN.objects.create(person=self.a, number='1')
SSN.objects.create(person=self.b, number='2')
merge(self.a, self.b, DELETE)
assert Person.objects.get(pk=self.b.pk).ssn.number == '1'
assert SSN.objects.count() == 1
def test_many2many_simple(self):
self.g.people.add(self.a)
merge(self.a, self.b)