3030 InstanceDestroyed ,
3131 InstanceNotHydrated ,
3232 InvalidFilters ,
33- NoResultsFound ,
33+ NoResultFound ,
34+ UnexpectedEmptyResult ,
3435 UnregisteredModel ,
3536)
3637from pyneo4j_ogm .fields .settings import NodeModelSettings , RelationshipModelSettings
@@ -130,7 +131,7 @@ async def create(self: T) -> T:
130131 instance is seen as `hydrated` and all methods can be called on it.
131132
132133 Raises:
133- NoResultsFound : If the query should return a result but does not.
134+ UnexpectedEmptyResult : If the query should return a result but does not.
134135
135136 Returns:
136137 T: The current model instance.
@@ -155,7 +156,7 @@ async def create(self: T) -> T:
155156
156157 logger .debug ("Checking if query returned a result" )
157158 if len (results ) == 0 or len (results [0 ]) == 0 or results [0 ][0 ] is None :
158- raise NoResultsFound ()
159+ raise UnexpectedEmptyResult ()
159160
160161 logger .debug ("Hydrating instance values" )
161162 setattr (self , "_element_id" , getattr (cast (T , results [0 ][0 ]), "_element_id" ))
@@ -174,7 +175,7 @@ async def update(self) -> None:
174175 Updates the corresponding node in the graph with the current instance values.
175176
176177 Raises:
177- NoResultsFound : If the query should return a result but does not.
178+ UnexpectedEmptyResult : If the query should return a result but does not.
178179 """
179180 deflated = self ._deflate ()
180181
@@ -203,7 +204,7 @@ async def update(self) -> None:
203204
204205 logger .debug ("Checking if query returned a result" )
205206 if len (results ) == 0 or len (results [0 ]) == 0 or results [0 ][0 ] is None :
206- raise NoResultsFound ()
207+ raise UnexpectedEmptyResult ()
207208
208209 logger .debug ("Resetting modified properties" )
209210 self ._db_properties = self .dict (exclude = self ._relationships_properties )
@@ -217,7 +218,7 @@ async def delete(self) -> None:
217218 another method is called on this instance, an `InstanceDestroyed` will be raised.
218219
219220 Raises:
220- NoResultsFound : If the query should return a result but does not.
221+ UnexpectedEmptyResult : If the query should return a result but does not.
221222 """
222223 logger .info ("Deleting node %s" , self )
223224 results , _ = await self ._client .cypher (
@@ -232,7 +233,7 @@ async def delete(self) -> None:
232233
233234 logger .debug ("Checking if query returned a result" )
234235 if len (results ) == 0 or len (results [0 ]) == 0 or results [0 ][0 ] is None :
235- raise NoResultsFound ()
236+ raise UnexpectedEmptyResult ()
236237
237238 logger .debug ("Marking instance as destroyed" )
238239 setattr (self , "_destroyed" , True )
@@ -245,7 +246,7 @@ async def refresh(self) -> None:
245246 Refreshes the current instance with the corresponding values from the graph.
246247
247248 Raises:
248- NoResultsFound : If the query should return a result but does not.
249+ UnexpectedEmptyResult : If the query should return a result but does not.
249250 """
250251 logger .info ("Refreshing node %s with values from database" , self )
251252 results , _ = await self ._client .cypher (
@@ -259,7 +260,7 @@ async def refresh(self) -> None:
259260
260261 logger .debug ("Checking if query returned a result" )
261262 if len (results ) == 0 or len (results [0 ]) == 0 or results [0 ][0 ] is None :
262- raise NoResultsFound ()
263+ raise UnexpectedEmptyResult ()
263264
264265 logger .debug ("Updating current instance" )
265266 self .__dict__ .update (results [0 ][0 ].__dict__ )
@@ -416,6 +417,7 @@ async def find_one(
416417 projections : Optional [Dict [str , str ]] = None ,
417418 auto_fetch_nodes : bool = False ,
418419 auto_fetch_models : Optional [List [Union [str , Type ["NodeModel" ]]]] = None ,
420+ raise_on_empty : bool = False ,
419421 ) -> Optional [Union [T , Dict [str , Any ]]]:
420422 """
421423 Finds the first node that matches `filters` and returns it. If no matching node is found,
@@ -430,9 +432,12 @@ async def find_one(
430432 identical option defined in `Settings`. Can not be used with projections. Defaults to `False`.
431433 auto_fetch_models (List[Union[str, Type["NodeModel"]]], optional): A list of models to auto-fetch.
432434 `auto_fetch_nodes` has to be set to `True` for this to have any effect. Defaults to `[]`.
435+ raise_on_empty (bool, optional): Whether to raise an `NoResultFound` if no match is found. Defaults to
436+ `False`.
433437
434438 Raises:
435439 InvalidFilters: If no filters or invalid filters are provided.
440+ NoResultFound: If no match is found and `raise_on_empty` is set to `True`.
436441
437442 Returns:
438443 T | Dict[str, Any] | None: A instance of the model or None if no match is found or a dictionary of the
@@ -500,6 +505,8 @@ async def find_one(
500505 or results [0 ][0 ] is None
501506 or (isinstance (results [0 ][0 ], dict ) and len (results [0 ][0 ]) == 0 )
502507 ):
508+ if raise_on_empty :
509+ raise NoResultFound (filters )
503510 return None
504511
505512 if isinstance (results [0 ][0 ], Node ):
@@ -654,7 +661,9 @@ async def find_many(
654661
655662 @classmethod
656663 @hooks
657- async def update_one (cls : Type [T ], update : Dict [str , Any ], filters : NodeFilters , new : bool = False ) -> Optional [T ]:
664+ async def update_one (
665+ cls : Type [T ], update : Dict [str , Any ], filters : NodeFilters , new : bool = False , raise_on_empty : bool = False
666+ ) -> Optional [T ]:
658667 """
659668 Finds the first node that matches `filters` and updates it with the values defined by
660669 `update`. If no match is found, `None` is returned instead.
@@ -664,9 +673,12 @@ async def update_one(cls: Type[T], update: Dict[str, Any], filters: NodeFilters,
664673 filters (NodeFilters): The filters to apply to the query.
665674 new (bool, optional): Whether to return the updated node. By default, the old node is
666675 returned. Defaults to `False`.
676+ raise_on_empty (bool, optional): Whether to raise an `NoResultFound` if no match is found. Defaults to
677+ `False`.
667678
668679 Raises:
669680 InvalidFilters: If no filters or invalid filters are provided.
681+ NoResultFound: If no match is found and `raise_on_empty` is set to `True`.
670682
671683 Returns:
672684 T | None: By default, the old node instance is returned. If `new` is set to `True`, the result
@@ -702,6 +714,8 @@ async def update_one(cls: Type[T], update: Dict[str, Any], filters: NodeFilters,
702714
703715 logger .debug ("Checking if query returned a result" )
704716 if len (results ) == 0 or len (results [0 ]) == 0 or results [0 ][0 ] is None :
717+ if raise_on_empty :
718+ raise NoResultFound (filters )
705719 return None
706720
707721 old_instance = results [0 ][0 ] if isinstance (results [0 ][0 ], cls ) else cls ._inflate (node = results [0 ][0 ])
@@ -830,17 +844,20 @@ async def update_many(
830844
831845 @classmethod
832846 @hooks
833- async def delete_one (cls : Type [T ], filters : NodeFilters ) -> int :
847+ async def delete_one (cls : Type [T ], filters : NodeFilters , raise_on_empty : bool = False ) -> int :
834848 """
835849 Finds the first node that matches `filters` and deletes it. If no match is found, a
836- `NoResultsFound ` is raised.
850+ `UnexpectedEmptyResult ` is raised.
837851
838852 Args:
839853 filters (NodeFilters): The filters to apply to the query.
854+ raise_on_empty (bool, optional): Whether to raise an `NoResultFound` if no match is found. Defaults to
855+ `False`.
840856
841857 Raises:
842- NoResultsFound : If the query should return a result but does not.
858+ UnexpectedEmptyResult : If the query should return a result but does not.
843859 InvalidFilters: If no filters or invalid filters are provided.
860+ NoResultFound: If no match is found and `raise_on_empty` is set to `True`.
844861
845862 Returns:
846863 int: The number of deleted nodes.
@@ -869,9 +886,11 @@ async def delete_one(cls: Type[T], filters: NodeFilters) -> int:
869886
870887 logger .debug ("Checking if query returned a result" )
871888 if len (result ) == 0 or len (result [0 ]) == 0 or result [0 ][0 ] is None :
872- raise NoResultsFound ()
889+ raise UnexpectedEmptyResult ()
873890
874891 logger .info ("Deleted %s nodes" , result [0 ][0 ])
892+ if result [0 ][0 ] == 0 and raise_on_empty :
893+ raise NoResultFound (filters )
875894 return result [0 ][0 ]
876895
877896 @classmethod
@@ -903,7 +922,7 @@ async def delete_many(cls: Type[T], filters: Optional[NodeFilters] = None) -> in
903922
904923 logger .debug ("Checking if query returned a result" )
905924 if len (results ) == 0 or len (results [0 ]) == 0 or results [0 ][0 ] is None :
906- raise NoResultsFound ()
925+ raise UnexpectedEmptyResult ()
907926
908927 logger .info ("Deleted %s nodes" , len (results ))
909928 return results [0 ][0 ]
@@ -940,7 +959,7 @@ async def count(cls: Type[T], filters: Optional[NodeFilters] = None) -> int:
940959
941960 logger .debug ("Checking if query returned a result" )
942961 if len (results ) == 0 or len (results [0 ]) == 0 or results [0 ][0 ] is None :
943- raise NoResultsFound ()
962+ raise UnexpectedEmptyResult ()
944963
945964 return results [0 ][0 ]
946965
@@ -970,7 +989,7 @@ def _inflate(cls: Type[T], node: Node) -> T:
970989 node (Node): Node to inflate.
971990
972991 Raises:
973- InflationFailure: Raised if inflating the node fails.
992+ InflationFailure: If inflating the node fails.
974993
975994 Returns:
976995 T: A new instance of the current model with the properties from the node instance.
@@ -1006,7 +1025,7 @@ def _build_auto_fetch(
10061025
10071026 Args:
10081027 nodes_to_fetch (List[Union[str, Type["NodeModel"]]] | None): The nodes to fetch. Can contain the actual
1009- Model of the Node or the model name as a string. If None, all nodes will be fetched. Defaults to None.
1028+ model of the node or the model name as a string. If ` None` , all nodes will be fetched. Defaults to ` None` .
10101029 ref (str, optional): The reference to use for the node. Defaults to "n".
10111030
10121031 Returns:
0 commit comments