error on 1:1 clash
This commit is contained in:
parent
8d4bab0563
commit
750061ebd6
@ -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)):
|
if not isinstance(from_obj, type(to_obj)):
|
||||||
raise ValueError("both objects must be of the same type")
|
raise ValueError("both objects must be of the same type")
|
||||||
|
|
||||||
@ -17,17 +32,17 @@ def merge(from_obj, to_obj):
|
|||||||
try:
|
try:
|
||||||
field = getattr(from_obj, accessor_name)
|
field = getattr(from_obj, accessor_name)
|
||||||
try:
|
try:
|
||||||
getattr(to_obj, accessor_name)
|
to_obj_field = getattr(to_obj, accessor_name)
|
||||||
except Exception as e:
|
raise OneToOneConflict("both fields have an attribute set for {}".format(accessor_name))
|
||||||
|
except ObjectDoesNotExist:
|
||||||
# doesn't exist, safe to overwrite
|
# doesn't exist, safe to overwrite
|
||||||
setattr(field, varname, to_obj)
|
setattr(field, varname, to_obj)
|
||||||
field.save()
|
field.save()
|
||||||
except Exception as e:
|
except ObjectDoesNotExist:
|
||||||
# from_obj one to one isn't set, skip
|
# from_obj one to one isn't set, skip
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
import pdb; pdb.set_trace()
|
raise NotImplementedError('unexpected relation type, please file a bug')
|
||||||
raise Exception('unknown code path')
|
|
||||||
|
|
||||||
for related in from_obj._meta.get_all_related_many_to_many_objects():
|
for related in from_obj._meta.get_all_related_many_to_many_objects():
|
||||||
accessor_name = related.get_accessor_name()
|
accessor_name = related.get_accessor_name()
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
from django.test import TestCase
|
from django.test import TestCase
|
||||||
from .models import Person, Number, SSN, Group
|
from .models import Person, Number, SSN, Group
|
||||||
from fkreplace import merge
|
from fkreplace import merge, OneToOneConflict
|
||||||
|
|
||||||
class MergeTests(TestCase):
|
class MergeTests(TestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
@ -44,6 +44,12 @@ class MergeTests(TestCase):
|
|||||||
assert SSN.objects.count() == 1
|
assert SSN.objects.count() == 1
|
||||||
|
|
||||||
# TODO: test one2one when there's a conflict
|
# 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):
|
def test_many2many_simple(self):
|
||||||
self.g.people.add(self.a)
|
self.g.people.add(self.a)
|
||||||
|
Loading…
Reference in New Issue
Block a user