Search code examples
neo4jpy2neo

Cannot cast GraphObject to Node


I have a defined AbstractQuery as a Child of GraphObject :

class AbstractQuery(GraphObject):

    __primarykey__ = "hash"

    hash = Property()
    projname = Property()

    def __init__(self, hash):
        self.hash = hash
        self.projname = ""  # TODO:initialize this

and iterate over all SQLQuery objects in my (already existing) graph and want to create a new AbstractQuery consisting of a hash. Any SQLQuery hashing to the hash determining the AbstractQuery should be connected:

def addAbstractionLayerSqlQueries(graph, logger=None):
    abstractQueryTable = getAbstractQueries(graph, logger)
    sqlqueries = graph.data("MATCH (n:SQLQuery) return n")

    if logger is not None:
        logger.info("abstracting {} queries".format(len(sqlqueries)))

    counter = 1
    for iterator in sqlqueries:
        query = iterator['n']
        if logger is not None:
            logger.info("abstracting query {}/{}".format(counter,
                                                         len(sqlqueries)))

        hash = sqlNormalizer.generate_normalized_query_hash(query['ts'])

        if hash not in abstractQueryTable:
            abstractQueryNode = al.AbstractQuery(hash)
            abstractQueryTable[hash] = abstractQueryNode
            graph.push(abstractQueryNode)

        rel = Relationship(query, "ABSTRACTSTO", abstractQueryTable[hash])
        graph.create(rel)
        counter = counter + 1

Before I start this process I extract a table (using the hash as key) of all already existing AbstractQueries to prevent creating the same AbstractQuery twice.

However, when I run the method I end up with the exception:

TypeError: Cannot cast AbstractQuery to Node

Why is this and how can I fix this?

I previously entered multiple SQLQueries into my graph by using this representation:

class SQLQuery(GraphObject):

    __primarykey__ = "uuid"

    uuid = Property()

    projname = Property()

    session = Property()
    user = Property()
    seq = Property()
    ts = Property()

    sql = Property()

    Statement = RelatedTo("SQLStatement")
    AbstractsTo = RelatedTo("AbstractQuery")

    def __init__(self, projname=None, session=None, user=None,
                 seq=None, ts=None, sql=None):
        self.projname = projname
        self.session = session
        self.user = user
        self.seq = seq
        self.ts = ts
        self.sql = sql
        self.uuid = "{} [{} {}] {}.{}.{}".format(type(self).__name__,
                                                 seq, ts, projname,
                                                 session, user)

As I was able to use this representation to represent and enter Nodes I am quite flabbergasted on why py2neo rejects my AbstractQuery class as a node in my addAbstractionLayerSqlQueries function.


Solution

  • You're mixing two layers of API. The OGM layer sits above the regular py2neo API and a GraphObject does not directly correspond to a Node (it contains other stuff too). Therefore, you cannot build a Relationship to or from a GraphObject directly.

    To access the core node behind your GraphObject, you can use my_object.__ogm__.node.