{"id":7446,"library":"neomodel","title":"neomodel Python OGM","description":"neomodel is an Object Graph Mapper (OGM) for the Neo4j graph database, providing a Pythonic way to interact with Neo4j. It allows developers to define graph models using Python classes, making it easier to store, retrieve, and query data in a Neo4j database. The current version is 6.1.0, with major releases approximately annually and patch releases as needed.","status":"active","version":"6.1.0","language":"en","source_language":"en","source_url":"https://github.com/neo4j-contrib/neomodel","tags":["neo4j","ogm","graph database","orm","data modeling"],"install":[{"cmd":"pip install neomodel","lang":"bash","label":"Install neomodel"}],"dependencies":[{"reason":"neomodel is an OGM for Neo4j, relying on the official Neo4j Python driver for database communication.","package":"neo4j","optional":false},{"reason":"Used internally for data validation and model definition.","package":"pydantic","optional":false}],"imports":[{"symbol":"StructuredNode","correct":"from neomodel import StructuredNode"},{"symbol":"StringProperty","correct":"from neomodel import StringProperty"},{"symbol":"IntegerProperty","correct":"from neomodel import IntegerProperty"},{"symbol":"RelationshipTo","correct":"from neomodel import RelationshipTo"},{"symbol":"RelationshipFrom","correct":"from neomodel import RelationshipFrom"},{"symbol":"db","correct":"from neomodel import db"},{"note":"The `neomodel.config` module was removed in v6.0.0. All configuration, including database connection, is now handled via the `neomodel.db` object.","wrong":"from neomodel import config; config.DATABASE_URL = 'bolt://...'","symbol":"config","correct":"from neomodel import db"}],"quickstart":{"code":"import os\nfrom neomodel import StructuredNode, StringProperty, IntegerProperty, RelationshipTo, db\n\n# Configure connection to Neo4j\nNEO4J_URL = os.environ.get('NEO4J_BOLT_URL', 'bolt://neo4j:password@localhost:7687')\ndb.set_connection(NEO4J_URL)\n\n# Define a Node model\nclass Person(StructuredNode):\n    uid = StringProperty(unique_index=True)\n    name = StringProperty(index=True, required=True)\n    age = IntegerProperty(index=True, default=0)\n\n    # Define a relationship\n    friends = RelationshipTo('Person', 'FRIENDS_WITH')\n\n# Ensure labels and constraints are created in the database\nPerson.ensure_indexes()\n\n# Create and save nodes\njim = Person(uid='jim001', name='Jim', age=32).save()\npam = Person(uid='pam001', name='Pam', age=30).save()\n\n# Create a relationship\njim.friends.connect(pam)\n\n# Retrieve and query\nfound_jim = Person.nodes.get(uid='jim001')\nprint(f\"Found: {found_jim.name}, Age: {found_jim.age}\")\n\n# Get friends\nprint(f\"{found_jim.name} is friends with:\")\nfor friend in found_jim.friends.all():\n    print(f\"- {friend.name}\")\n\n# Clear database for example (use with caution in production)\n# db.cypher_query(\"MATCH (n) DETACH DELETE n\")\ndb.close_connection()","lang":"python","description":"This quickstart demonstrates how to connect to a Neo4j database, define a `StructuredNode` model with properties and relationships, create and save nodes, establish relationships, and query the graph using neomodel. It uses environment variables for secure connection details."},"warnings":[{"fix":"Replace `neomodel.config.DATABASE_URL = '...'` with `neomodel.db.set_connection('...')`. Other config settings previously in `neomodel.config` are now set via `neomodel.db.set_config(...)`.","message":"The `neomodel.config` module has been entirely removed in v6.0.0. All configuration, especially database connection details, must now be managed through the `neomodel.db` object.","severity":"breaking","affected_versions":">=6.0.0"},{"fix":"Change `node.refresh()` to `node.reload()`.","message":"The `StructuredNode.refresh()` method was removed in v6.0.0. Use `StructuredNode.reload()` instead to fetch the latest state of the node from the database.","severity":"breaking","affected_versions":">=6.0.0"},{"fix":"Migrate calls from `db.cypher_query(query, params)` to `db.run(query, params)`. The return format might differ slightly, consult `db.run` documentation.","message":"The `db.cypher_query()` method is deprecated and should be replaced with `db.run()`. While `cypher_query` might still work, `db.run` offers a more consistent interface and better handles parameters.","severity":"breaking","affected_versions":">=6.0.0"},{"fix":"After defining your models, call `YourModel.ensure_indexes()` for each model, or `neomodel.db.install_all_labels()` to apply all defined constraints and indexes.","message":"Unique constraints and indexes defined on `StructuredNode` properties (e.g., `unique_index=True`, `index=True`) are not automatically created in the Neo4j database upon model definition. You must explicitly call `YourModel.ensure_indexes()` or `db.install_all_labels()`.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Ensure your project's Python environment is 3.10 or higher. Use `python --version` to check and upgrade if necessary.","message":"neomodel versions 6.x.x require Python 3.10 or newer. Attempting to install or run on older Python versions will result in dependency resolution failures or runtime errors.","severity":"gotcha","affected_versions":">=6.0.0"}],"env_vars":null,"last_verified":"2026-04-16T00:00:00.000Z","next_check":"2026-07-15T00:00:00.000Z","problems":[{"fix":"Use `from neomodel import db; db.set_connection('bolt://user:password@host:port')` to configure your database connection.","cause":"Attempting to set the Neo4j connection URL using the deprecated `neomodel.config` module, which was removed in neomodel v6.0.0.","error":"AttributeError: module 'neomodel.config' has no attribute 'DATABASE_URL'"},{"fix":"Verify that your Neo4j instance is running and accessible. Double-check the connection URL, username, and password passed to `db.set_connection`. Ensure correct firewall rules or network configuration.","cause":"The Neo4j database is not running, is inaccessible from the client, or the connection details (URL, username, password) provided to `db.set_connection` are incorrect.","error":"neo4j.exceptions.ServiceUnavailable: Failed to establish connection"},{"fix":"Before serializing, convert neomodel objects into a JSON-friendly format. For nodes, you can often use `node.__properties__` to get a dictionary of its simple properties, or manually select attributes. For relationships, you might need to extract specific properties like `type` or related nodes.","cause":"Attempting to directly serialize a `StructuredNode` or `Relationship` object, which are not standard Python dicts and contain complex internal structures that JSON serializers cannot handle by default.","error":"TypeError: Object of type <class 'neomodel.relationship.Relationship'> is not JSON serializable"},{"fix":"When creating a new node, ensure all `required=True` properties are provided a value, or define a `default` value for them in your model definition (e.g., `my_property = StringProperty(required=True, default='N/A')`).","cause":"You are trying to create a `StructuredNode` instance without providing a value for a property that is marked `required=True` and does not have a `default` value defined.","error":"ValueError: No default value for property 'my_required_property' defined"},{"fix":"Before creating a new node, check if a node with the unique property already exists using `YourModel.nodes.get_or_none(your_unique_prop=value)`. If it exists, retrieve and use it; otherwise, create a new one. Also ensure `YourModel.ensure_indexes()` or `db.install_all_labels()` has been run to create the unique constraint in Neo4j.","cause":"You are attempting to create a node with a property value (e.g., an `email` address) that is marked `unique_index=True` on your model, but another node with the same value already exists in the database.","error":"neomodel.exceptions.ConstraintValidationFailed: Node (X) already exists with label '...' and property '...' = '...'"}]}