[Python] Turning on `IF NOT EXISTS` while creating schemas and relationships in neo4j /...

Discussão em 'Python' iniciado por Stack, Março 8, 2025.

  1. Stack

    Stack Membro Participativo

    Recently I switched from using Cypher queries to neomodel OGM. Although it simplified codebase, there's still an issue I can't solve. While using Cypher, I could simply write CREATE <object> IF NOT EXISTS, and execution plan would be understandable enough: if exists - do nothing, if doesn't - create. After switching to neomodel, I've created following:

    • Service responsible for calling Neo4J using Neomodel:

    from models.neo4j_models import (
    ...
    )
    from neomodel import config, db
    ...


    class GraphDBService:
    def __init__(self, uri: str, username: str, password: str):
    ...
    self._initialize_db() # IMPORTANT: called every time when service is created
    ...

    def _initialize_db(self) -> None:
    """Initialize database with constraints and indexes"""

    try:
    db.install_all_labels()
    logger.info("Neo4j constraints and indexes installed via neomodel")
    except Exception as e:
    logger.error(f"Error initializing Neo4j schema: {str(e)}", exc_info=True)
    raise GraphDBError(f"Failed to initialize Neo4j schema: {str(e)}")

    • Model to be created (models.neo4j_models):

    from neomodel import (
    StringProperty, ...
    )

    class Company(StructuredNode):
    """
    Company node representing an organization where a person has worked
    """
    name = StringProperty(unique_index=True, required=True)
    ...


    It works as expected (according to their doc), but what I do not like is following:

    • Use service 1st time
      • All models, relationships and so on are created (as expected)
    • Disconnect from service and reconnect again
      • All models and so on are created again (as expected)

    During second round, my trace is heavily cluttered by logs of following type:

    cv-storage-service-1 | Found models.neo4j_models.Company
    cv-storage-service-1 | + Creating node unique constraint for name on label Company for class models.neo4j_models.Company
    cv-storage-service-1 | {code: Neo.ClientError.Schema.EquivalentSchemaRuleAlreadyExists} {message: An equivalent constraint already exists, 'Constraint( id=17, name='constraint_unique_Company_name', type='NODE PROPERTY UNIQUENESS', schema=:)Company {name}), ownedIndex=16 )'.}


    Although I could find a solution checking whether calling _initialize_db() is justified or not, I would prefer simpler solution: just to pass a construct/flag/whatever that will tell neo sort of IF <this> NOT EXISTS, create. How could I do that?

    If passing extra param is not an option, how could I change logs dropping straight from Neo4J? Core issue here is that all these "Errors" contain word Error, thus awfully increasing number of errors in log, and instead of having 100x+ Sorry, can't create, it already exists INFO-messages I get 100x+ "errors" that need not to be solved (from my point of view).

    Workaround in this GitHub issue works as of now, but to be honest, I'd prefer to get a solution rather than a workaround :)


    Tech: MacOS Sonoma 14.6.1, Python 3.11, neomodel 5.4.4

    Continue reading...

Compartilhe esta Página