cancel
Showing results for 
Search instead for 
Did you mean: 

Head's Up! These forums are read-only. All users and content have migrated. Please join us at community.neo4j.com.

Py2neo -- how to fix circular references?

We are trying to build a full OGM for a Python/Flask based backend which uses Neo4j.

The problem I am running into is with the RelatedTo and RelatedFrom parts of Py2neo.ogm framework.

Naturally, if my graph has a structure like (a)-[:LINKS_TO]->(b) I would want OGM properties:
class a(GraphObject):
links_to = RelatedTo(b, "HAS")
class b(GraphObject):
linked_to = RelatedFrom(a, "HAS")

Note: I have used the objects a and b here not 'a' and 'b'. When I switch to using quotes it does not seem to retrieve the GraphObjects at all.

This causes Python to freak out with the circular dependencies since a is referencing b before it is defined.

I have not found a way to "forward declare" classes in Python like you can in some other languages.

This must be an extremely common situation in Py2neo, how are others solving it?

1 REPLY 1

This question has an answer here: Py2neo RelatedTo/From cause circular import errors (#740).

Here is what technige said:

The string variants of the class names are intended to help work around exactly this problem. If class A references class B before B is defined, the name of B will need to be passed in quotes.

This is precisely what the example you reference is doing:

class Movie(GraphObject):
    __primarykey__ = "title"

    title = Property()
    tag_line = Property("tagline")
    released = Property()

    actors = RelatedFrom("Person", "ACTED_IN")
    directors = RelatedFrom("Person", "DIRECTED")
    producers = RelatedFrom("Person", "PRODUCED")


class Person(GraphObject):
    __primarykey__ = "name"

    name = Property()
    born = Property()

    acted_in = RelatedTo(Movie)
    directed = RelatedTo(Movie)
    produced = RelatedTo(Movie)

Here, the Person class does not exist when the Movie class is being defined. Therefore, a direct reference to Person would fail. Putting the name of the method in quotes causes the class to be lazily resolved after the entire module has loaded.

On the other hand, the Person class itself can of course directly reference the Movie class as the latter will already have been defined.

I've implemented the accepted solution myself, with success! Using the string variants solves the problem.

Nodes 2022
Nodes
NODES 2022, Neo4j Online Education Summit

All the sessions of the conference are now available online