NebulaGraph Python Client 5.3.0
Loading...
Searching...
No Matches
graph_type.py
1# Copyright 2025 vesoft-inc
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7# http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14
15from pydantic import BaseModel
16from typing_extensions import TYPE_CHECKING, Dict, List, Optional, Self, Type, Union
17
18if TYPE_CHECKING:
19 from nebulagraph_python.orm.model import EdgeModel, NodeModel
20
21
22class PropTypeRow(BaseModel):
23 property_name: str
24 data_type: str
25 nullable: bool
26 default: Optional[str]
27
28
29class WithPropType(BaseModel):
30 properties: Dict[str, PropTypeRow]
31 pr_or_me_keys: List[str]
32
33
35 node_type: str
36 labels: List[str]
37
38 def to_gql(self) -> str:
39 return f"NODE `{self.node_type}` ({_labels_to_gql(self.labels)} {{ {_props_to_gql(self.properties)} PRIMARY KEY ({', '.join('`' + x + '`' for x in self.pr_or_me_keys)}) }})"
40
41
43 edge_type: str
44 src_node_type: str
45 dst_node_type: str
46 labels: List[str]
47
48 @property
49 def edge_pattern(self) -> str:
50 return f"({self.src_node_type})-[{self.edge_type}]->({self.dst_node_type})"
51
52 def to_gql(self) -> str:
53 return f"EDGE `{self.edge_type}` (`{self.src_node_type}`)-[{_labels_to_gql(self.labels)} {{ {_props_to_gql(self.properties)} MULTIEDGE KEY ({', '.join('`' + x + '`' for x in self.pr_or_me_keys)}) }}]->(`{self.dst_node_type}`)"
54
55
56class GraphType(BaseModel):
57 name: str
58 nodes: Dict[str, NodeType]
59 edges: Dict[str, EdgeType]
60
61 @classmethod
62 def from_models(
63 cls,
64 graph_type_name: str,
65 models: List[Union[Type["NodeModel"], Type["EdgeModel"]]],
66 ) -> Self:
67 from nebulagraph_python.orm.model import EdgeModel, NodeModel
68
69 nodes = {}
70 edges = {}
71 for model in models:
72 if issubclass(model, NodeModel):
73 nodes[model.get_type()] = model.to_type()
74 elif issubclass(model, EdgeModel):
75 edges[model.get_type()] = model.to_type()
76 return cls(name=graph_type_name, nodes=nodes, edges=edges)
77
78 def to_gql(self) -> str:
79 return (
80 f"CREATE GRAPH TYPE {self.name} {{\n"
81 + ",\n".join([x.to_gql() for x in self.nodes.values()])
82 + ",\n"
83 + ",\n".join([x.to_gql() for x in self.edges.values()])
84 + "\n"
85 + "}"
86 )
87
88
89def _labels_to_gql(labels: List[str]) -> str:
90 return (":" + "&".join(f"`{x}`" for x in labels)) if labels else ""
91
92
93def _props_to_gql(props: Dict[str, PropTypeRow]) -> str:
94 if not props:
95 return ""
96 return (
97 ", ".join(
98 [
99 f"`{k}` {v.data_type} {'' if v.nullable else 'NOT NULL'} {f'DEFAULT {v.default}' if v.default is not None else ''}"
100 for k, v in props.items()
101 ]
102 )
103 + ", "
104 )