function create_node_with_relationship_v1
Creates a new node in a Neo4j graph database and optionally establishes a directed relationship with an existing node in a single atomic operation.
/tf/active/vicechatdev/CDocs single class/db/db_operations.py
75 - 162
moderate
Purpose
This function provides an atomic operation to create a node and link it to an existing node in Neo4j. It automatically generates a UID and creation timestamp if not provided, supports bidirectional relationships (OUTGOING or INCOMING), and allows properties on both the node and relationship. This is useful for maintaining referential integrity and reducing the number of database round-trips when creating connected graph structures.
Source Code
def create_node_with_relationship(
label: str,
properties: Dict[str, Any],
to_node_uid: str = None,
relationship_type: str = None,
relationship_direction: str = "OUTGOING",
relationship_properties: Dict[str, Any] = None
) -> Optional[Dict[str, Any]]:
"""
Create a node and immediately establish a relationship with another node.
Parameters
----------
label : str
The node label for the new node
properties : dict
Properties for the new node
to_node_uid : str
UID of the node to create a relationship with
relationship_type : str
Type of relationship to create
relationship_direction : str
Direction of relationship: "OUTGOING" (new node -> existing node)
or "INCOMING" (existing node -> new node)
relationship_properties : dict
Properties for the relationship
Returns
-------
dict
The created node properties
"""
try:
# Generate a unique ID if not provided
if 'UID' not in properties:
properties['UID'] = str(uuid.uuid4())
# Add creation timestamp if not provided
if 'createdDate' not in properties:
properties['createdDate'] = datetime.now()
# If no relationship needed, just create the node
if not to_node_uid or not relationship_type:
return create_node(label, properties)
# Set relationship direction in query
if relationship_direction == "OUTGOING":
rel_pattern = "-[r:%s]->(n2)" % relationship_type
else:
rel_pattern = "<-[r:%s]-(n2)" % relationship_type
# Build the query with relationship creation
query = f"""
MATCH (n2 {{UID: $to_node_uid}})
CREATE (n:{label} $node_props) {rel_pattern}
"""
# Add relationship properties if provided
if relationship_properties:
rel_props_str = " {" + ", ".join([f"{k}: ${k}" for k in relationship_properties.keys()]) + "}"
query = query.replace(f"r:{relationship_type}", f"r:{relationship_type}{rel_props_str}")
query += " RETURN n"
# Prepare parameters
params = {
"to_node_uid": to_node_uid,
"node_props": properties
}
# Add relationship properties to params
if relationship_properties:
params.update(relationship_properties)
# Execute the query
result = run_query(query, params)
# Return created node properties
if result and 'n' in result[0]:
return dict(result[0]['n'])
return properties
except Exception as e:
logger.error(f"Error creating node with relationship: {str(e)}")
import traceback
logger.error(traceback.format_exc())
return None
Parameters
| Name | Type | Default | Kind |
|---|---|---|---|
label |
str | - | positional_or_keyword |
properties |
Dict[str, Any] | - | positional_or_keyword |
to_node_uid |
str | None | positional_or_keyword |
relationship_type |
str | None | positional_or_keyword |
relationship_direction |
str | 'OUTGOING' | positional_or_keyword |
relationship_properties |
Dict[str, Any] | None | positional_or_keyword |
Parameter Details
label: The Neo4j node label (type) for the new node being created. This is a string that categorizes the node (e.g., 'Person', 'Document', 'Event').
properties: A dictionary containing the properties (attributes) to assign to the new node. If 'UID' is not included, a UUID will be auto-generated. If 'createdDate' is not included, the current datetime will be added automatically.
to_node_uid: Optional. The unique identifier (UID) of an existing node to create a relationship with. If None or not provided, only the node is created without any relationship.
relationship_type: Optional. The type/label of the relationship to create between the new node and the existing node (e.g., 'KNOWS', 'CREATED_BY', 'BELONGS_TO'). Required if to_node_uid is provided.
relationship_direction: Specifies the direction of the relationship. 'OUTGOING' means the new node points to the existing node (new->existing). 'INCOMING' means the existing node points to the new node (existing->new). Defaults to 'OUTGOING'.
relationship_properties: Optional. A dictionary of properties to attach to the relationship itself (e.g., {'since': '2023-01-01', 'weight': 0.8}). Can be None if no relationship properties are needed.
Return Value
Type: Optional[Dict[str, Any]]
Returns a dictionary containing the properties of the newly created node if successful, including any auto-generated fields like UID and createdDate. Returns None if an error occurs during node creation or relationship establishment. The dictionary keys correspond to the node's property names and values are the property values.
Dependencies
logginguuidtypingdatetimeneo4jtracebackCDocs.dbCDocs.db.schema_manager
Required Imports
import logging
import uuid
from typing import Dict, Any, Optional
from datetime import datetime
from neo4j import Driver, Session, Transaction, Record
from neo4j.exceptions import ServiceUnavailable, ClientError
from CDocs.db import get_driver
from CDocs.db.schema_manager import NodeLabels, RelTypes
Conditional/Optional Imports
These imports are only needed under specific conditions:
import traceback
Condition: only used in exception handling for detailed error logging
Required (conditional)Usage Example
# Create a new Document node linked to an existing User node
user_uid = 'user-123-abc'
# Example 1: Create node with outgoing relationship
doc_properties = {
'title': 'Project Proposal',
'content': 'This is the proposal content',
'status': 'draft'
}
new_doc = create_node_with_relationship(
label='Document',
properties=doc_properties,
to_node_uid=user_uid,
relationship_type='CREATED_BY',
relationship_direction='OUTGOING',
relationship_properties={'timestamp': datetime.now(), 'role': 'author'}
)
if new_doc:
print(f"Created document with UID: {new_doc['UID']}")
# Example 2: Create node without relationship
standalone_node = create_node_with_relationship(
label='Tag',
properties={'name': 'important', 'color': 'red'}
)
# Example 3: Create node with incoming relationship
comment_props = {'text': 'Great work!', 'rating': 5}
comment = create_node_with_relationship(
label='Comment',
properties=comment_props,
to_node_uid=doc_properties['UID'],
relationship_type='COMMENTED_ON',
relationship_direction='INCOMING'
)
Best Practices
- Always provide both to_node_uid and relationship_type together, or neither. Providing only one will result in just creating a node without a relationship.
- Ensure the target node (to_node_uid) exists in the database before calling this function, as the query will fail if it doesn't match any existing node.
- Use meaningful relationship_type names that follow Neo4j conventions (typically UPPERCASE_WITH_UNDERSCORES).
- Be aware that this function auto-generates UID and createdDate if not provided in properties, which may override your intended values if you're not careful.
- Handle the None return value appropriately, as it indicates an error occurred during the operation.
- Consider wrapping this function call in a try-except block for additional error handling at the application level.
- The function uses string formatting for Cypher query construction, which is generally safe here but be cautious about the relationship_type parameter to avoid injection issues.
- Relationship properties are merged into the query parameters, so avoid key collisions between relationship_properties and other parameters like 'to_node_uid' or 'node_props'.
- The function depends on external run_query() and create_node() functions that must be properly implemented and available in scope.
Tags
Similar Components
AI-powered semantic similarity - components with related functionality:
-
function create_node_with_relationship 98.0% similar
-
function create_node_and_ensure_relationships 88.8% similar
-
function create_node_v1 69.5% similar
-
function create_relationship 68.8% similar
-
function create_node_with_uid 68.4% similar