2

With the ogm module of py2neo you can build objects for nodes in neo4j:

class Person(GraphObject):
    __primarykey__ = 'name'

    name = Property()

    def __init__(self, name):
        self.name = name


peter = Person('peter')

graph.create(peter)

Is it possible to add dynamic properties to the Person object?

peter = Person('peter')

# this does not work
peter.last_name = 'jackson'

graph.create(peter)

It would be possible to first create a node and add properties later but it would be easier to create GraphObjects with dynamic properties.

Martin Preusse
  • 9,151
  • 12
  • 48
  • 80

1 Answers1

1

I came up with a kind of brute-force solution for this problem:

Rip out the class of your object, beat in the new property into the class and stuff it back into your object before it realizes what just happened :D

from py2neo.ogm import GraphObject, Property
from py2neo import Graph

class Person(GraphObject):
    __primarykey__ = "name"

    name = Property()

    def __init__(self, name):
        self.name = name

    def add_new_property(self, name, value):
        self.__class__ = type(
            type(self).__name__, (self.__class__,), {name: Property()}
        )
        setattr(self, name, value)


peter = Person("peter")
peter.add_new_property("lastname", "jackson")


g = Graph(host="localhost", user="neo4j", password="neo4j")
tx = g.begin()
tx.merge(peter)
tx.commit()

Works in this tiny lab setup. but should be tested in a more complex environment.

Cheers from the DZD :)

Tim

Adam B
  • 3,662
  • 2
  • 24
  • 33
Tim B
  • 68
  • 5
  • It works but the aggressive vocabulary you need to describe your solution should be a warning ;) Are the existing properties copied to the new class? – Martin Preusse Nov 27 '19 at 18:05
  • Yep, the second argument for type(), are the baseclasses(as tuple). So the old class with all it properties will be used as the base for the "new" class. Usually its not recommended to switch the class of a living object, but this case happens in a pretty controlled manner, as we are just adding a new property and not changing anything else. The values of the old properties will be preserved, as they are mounted on the object itself, which is still the same. – Tim B Nov 27 '19 at 20:05