Skip to content

Commit b8d0b43

Browse files
committed
Fixes #903 by reintroducing entity-level label/key overrides
1 parent 591db36 commit b8d0b43

File tree

2 files changed

+97
-4
lines changed

2 files changed

+97
-4
lines changed

py2neo/data/__init__.py

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -279,12 +279,21 @@ def __db_merge__(self, tx, primary_label=None, primary_key=None):
279279
node_dict = {}
280280
for node in self.nodes:
281281
if not self._is_bound(node, graph):
282-
if node.__model__ is None:
283-
p_label = primary_label
284-
p_key = primary_key
285-
else:
282+
# Determine primary label
283+
if node.__primarylabel__ is not None:
284+
p_label = node.__primarylabel__
285+
elif node.__model__ is not None:
286286
p_label = node.__model__.__primarylabel__ or primary_label
287+
else:
288+
p_label = primary_label
289+
# Determine primary key
290+
if node.__primarykey__ is not None:
291+
p_key = node.__primarykey__
292+
elif node.__model__ is not None:
287293
p_key = node.__model__.__primarykey__ or primary_key
294+
else:
295+
p_key = primary_key
296+
# Add node to the node dictionary
288297
key = (p_label, p_key, frozenset(node.labels))
289298
node_dict.setdefault(key, []).append(node)
290299

@@ -611,6 +620,12 @@ class Node(Entity):
611620
#: OGM model class
612621
__model__ = None
613622

623+
#: Entity-level override for merge label
624+
__primarylabel__ = None
625+
626+
#: Entity-level override for merge key
627+
__primarykey__ = None
628+
614629
@classmethod
615630
def ref(cls, graph, identity):
616631
obj = cls()

test/integration/test_merge.py

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -347,3 +347,81 @@ class ModelB(Model):
347347
graph.merge(node, label_a, "a")
348348
assert node.identity != a_id
349349
assert node.identity == b_id
350+
351+
352+
def test_can_merge_node_with_merge_arguments(graph):
353+
graph.delete_all()
354+
a = Node("Person", name="Alice")
355+
graph.merge(a, "Person", "name")
356+
assert graph.nodes.match("Person", name="Alice").first() == a
357+
358+
359+
def test_can_merge_node_with_primary_label_and_key(graph):
360+
graph.delete_all()
361+
a = Node("Person", name="Alice")
362+
a.__primarylabel__ = "Person"
363+
a.__primarykey__ = "name"
364+
graph.merge(a)
365+
assert graph.nodes.match("Person", name="Alice").first() == a
366+
367+
368+
def test_can_merge_node_with_model(graph):
369+
from py2neo.ogm import Model
370+
371+
class Person(Model):
372+
__primarylabel__ = "Person"
373+
__primarykey__ = "name"
374+
375+
graph.delete_all()
376+
377+
a = Node("Person", name="Alice")
378+
a.__model__ = Person
379+
graph.merge(a)
380+
assert graph.nodes.match("Person", name="Alice").first() == a
381+
382+
383+
def test_can_merge_node_with_model_overriding_arguments(graph):
384+
from py2neo.ogm import Model
385+
386+
class Person(Model):
387+
__primarylabel__ = "Person"
388+
__primarykey__ = "name"
389+
390+
graph.delete_all()
391+
392+
a = Node("Person", name="Alice")
393+
a.__model__ = Person
394+
graph.merge(a, "Human", "nom")
395+
assert graph.nodes.match("Person", name="Alice").first() == a
396+
397+
398+
def test_can_merge_node_with_primary_label_overriding_model(graph):
399+
from py2neo.ogm import Model
400+
401+
class Person(Model):
402+
__primarylabel__ = "Human"
403+
__primarykey__ = "name"
404+
405+
graph.delete_all()
406+
407+
a = Node("Person", name="Alice")
408+
a.__model__ = Person
409+
a.__primarylabel__ = "Person"
410+
graph.merge(a)
411+
assert graph.nodes.match("Person", name="Alice").first() == a
412+
413+
414+
def test_can_merge_node_with_primary_key_overriding_model(graph):
415+
from py2neo.ogm import Model
416+
417+
class Person(Model):
418+
__primarylabel__ = "Person"
419+
__primarykey__ = "nom"
420+
421+
graph.delete_all()
422+
423+
a = Node("Person", name="Alice")
424+
a.__model__ = Person
425+
a.__primarykey__ = "name"
426+
graph.merge(a)
427+
assert graph.nodes.match("Person", name="Alice").first() == a

0 commit comments

Comments
 (0)