0
# Node Management
1
2
Core functionality for defining and working with graph nodes in neomodel. This includes model definitions, CRUD operations, property management, and both synchronous and asynchronous implementations.
3
4
## Capabilities
5
6
### Structured Node Classes
7
8
Base classes for defining graph node models with property definitions, relationship management, and database operations.
9
10
```python { .api }
11
class StructuredNode:
12
"""
13
Base class for all node models in synchronous mode.
14
15
Provides CRUD operations, querying, and relationship management.
16
"""
17
18
def save(self):
19
"""
20
Save the node to Neo4j database.
21
22
Returns:
23
self: The saved node instance
24
"""
25
26
def delete(self):
27
"""
28
Delete the node from Neo4j database.
29
30
Returns:
31
bool: True if deletion was successful
32
"""
33
34
def refresh(self):
35
"""
36
Reload the node's properties from the database.
37
38
Returns:
39
self: The refreshed node instance
40
"""
41
42
@classmethod
43
def create(cls, **kwargs):
44
"""
45
Create a new node instance and save it to the database.
46
47
Args:
48
**kwargs: Property values for the new node
49
50
Returns:
51
Instance of the node class
52
"""
53
54
@classmethod
55
def get_or_create(cls, defaults=None, **kwargs):
56
"""
57
Get an existing node or create a new one if it doesn't exist.
58
59
Args:
60
defaults (dict, optional): Default values for creation
61
**kwargs: Lookup parameters
62
63
Returns:
64
tuple: (node_instance, created_boolean)
65
"""
66
67
@classmethod
68
def create_or_update(cls, **kwargs):
69
"""
70
Create a new node or update existing one based on unique properties.
71
72
Args:
73
**kwargs: Property values
74
75
Returns:
76
Instance of the node class
77
"""
78
79
class AsyncStructuredNode:
80
"""
81
Base class for all node models in asynchronous mode.
82
83
Provides async CRUD operations, querying, and relationship management.
84
"""
85
86
async def save(self):
87
"""
88
Asynchronously save the node to Neo4j database.
89
90
Returns:
91
self: The saved node instance
92
"""
93
94
async def delete(self):
95
"""
96
Asynchronously delete the node from Neo4j database.
97
98
Returns:
99
bool: True if deletion was successful
100
"""
101
102
async def refresh(self):
103
"""
104
Asynchronously reload the node's properties from the database.
105
106
Returns:
107
self: The refreshed node instance
108
"""
109
110
@classmethod
111
async def create(cls, **kwargs):
112
"""
113
Asynchronously create a new node instance and save it to the database.
114
115
Args:
116
**kwargs: Property values for the new node
117
118
Returns:
119
Instance of the node class
120
"""
121
122
@classmethod
123
async def get_or_create(cls, defaults=None, **kwargs):
124
"""
125
Asynchronously get an existing node or create a new one.
126
127
Args:
128
defaults (dict, optional): Default values for creation
129
**kwargs: Lookup parameters
130
131
Returns:
132
tuple: (node_instance, created_boolean)
133
"""
134
135
@classmethod
136
async def create_or_update(cls, **kwargs):
137
"""
138
Asynchronously create a new node or update existing one.
139
140
Args:
141
**kwargs: Property values
142
143
Returns:
144
Instance of the node class
145
"""
146
```
147
148
### Property Management
149
150
Classes responsible for property handling, validation, and data transformation between Python and Neo4j formats.
151
152
```python { .api }
153
class PropertyManager:
154
"""
155
Base class for property management in synchronous mode.
156
157
Handles property inflation/deflation, validation, and database interaction.
158
"""
159
160
class AsyncPropertyManager:
161
"""
162
Base class for property management in asynchronous mode.
163
164
Handles async property inflation/deflation, validation, and database interaction.
165
"""
166
```
167
168
## Usage Examples
169
170
### Basic Node Definition
171
172
```python
173
from neomodel import StructuredNode, StringProperty, IntegerProperty
174
175
class Person(StructuredNode):
176
name = StringProperty(unique_index=True, required=True)
177
age = IntegerProperty()
178
email = StringProperty()
179
180
# Create and save a node
181
person = Person(name="Alice", age=30, email="alice@example.com").save()
182
183
# Alternative creation method
184
person = Person.create(name="Bob", age=25)
185
186
# Get or create pattern
187
person, created = Person.get_or_create(
188
name="Charlie",
189
defaults={'age': 35, 'email': 'charlie@example.com'}
190
)
191
```
192
193
### Async Node Operations
194
195
```python
196
from neomodel import AsyncStructuredNode, StringProperty, IntegerProperty
197
198
class AsyncPerson(AsyncStructuredNode):
199
name = StringProperty(unique_index=True, required=True)
200
age = IntegerProperty()
201
202
# Async operations
203
async def create_person():
204
person = await AsyncPerson.create(name="David", age=40)
205
await person.save()
206
207
# Get or create async
208
person, created = await AsyncPerson.get_or_create(
209
name="Eve",
210
defaults={'age': 28}
211
)
212
213
return person
214
```
215
216
### Node Querying
217
218
```python
219
# Query through the nodes manager
220
all_people = Person.nodes.all()
221
alice = Person.nodes.get(name="Alice")
222
adults = Person.nodes.filter(age__gte=18)
223
224
# Async querying
225
async def query_people():
226
all_people = await AsyncPerson.nodes.all()
227
alice = await AsyncPerson.nodes.get(name="Alice")
228
return all_people, alice
229
```
230
231
### Semi-structured Nodes
232
233
Special node classes that allow storing properties not defined in the class schema alongside the defined properties.
234
235
```python { .api }
236
class SemiStructuredNode(StructuredNode):
237
"""
238
Base class for synchronous semi-structured nodes.
239
240
Allows properties to be stored on a node that aren't specified in its
241
definition. Conflicting properties with class attributes raise DeflateConflict.
242
"""
243
__abstract_node__ = True
244
245
@classmethod
246
def inflate(cls, node): ...
247
248
@classmethod
249
def deflate(cls, node_props, obj=None, skip_empty=False): ...
250
251
class AsyncSemiStructuredNode(AsyncStructuredNode):
252
"""
253
Base class for asynchronous semi-structured nodes.
254
255
Allows properties to be stored on a node that aren't specified in its
256
definition. Conflicting properties with class attributes raise DeflateConflict.
257
"""
258
__abstract_node__ = True
259
260
@classmethod
261
def inflate(cls, node): ...
262
263
@classmethod
264
def deflate(cls, node_props, obj=None, skip_empty=False): ...
265
```
266
267
#### Semi-structured Usage Example
268
269
```python
270
from neomodel import StringProperty, IntegerProperty
271
from neomodel.contrib.sync_.semi_structured import SemiStructuredNode
272
from neomodel.contrib.async_.semi_structured import AsyncSemiStructuredNode
273
274
class Person(SemiStructuredNode):
275
name = StringProperty(required=True)
276
age = IntegerProperty()
277
278
# Create node with extra properties not in schema
279
person = Person(
280
name='Tim',
281
age=25,
282
weight=70, # Extra property
283
occupation='Engineer' # Extra property
284
).save()
285
286
# Access both defined and extra properties
287
print(person.name) # Defined property
288
print(person.weight) # Extra property
289
print(person.occupation) # Extra property
290
291
# Adding conflicting properties will raise DeflateConflict
292
person.name = "Updated Name" # OK - defined property
293
# person.save = "invalid" # Would raise DeflateConflict (conflicts with method)
294
```
295
296
## Types
297
298
```python { .api }
299
# Node operation return types
300
NodeInstance = Union[StructuredNode, AsyncStructuredNode]
301
CreateResult = Tuple[NodeInstance, bool] # (instance, was_created)
302
```