Ejemplo n.º 1
0
    def fetch_properties(
            self, prop_name: str,
            prop_type: Callable[["Property"], "Property"]) -> List["Property"]:
        query = f"""
            {{
                res(func: eq(node_key, "{self.node_key}")) @cascade {{
                    uid,
                    node_key,
                    node_type: dgraph.type,
                    {prop_name}
                }}
            
            }}
        """
        txn = self.dgraph_client.txn(read_only=True)
        try:
            res = json.loads(txn.query(query).json)
        finally:
            txn.discard()
        raw_props = res["res"]

        if not raw_props:
            return []

        props = [prop_type(p[prop_name]) for p in raw_props]
        props = [unescape_dgraph_str(prop) for prop in props]
        return props
Ejemplo n.º 2
0
    def fetch_property(
        self, prop_name: str, prop_type: Callable[["Property"], "Property"]
    ) -> Optional[Union[str, int]]:
        node_key_prop = ""
        if prop_name != "node_key":
            node_key_prop = "node_key"
        query = f"""
            {{
                res(func: eq(node_key, "{self.node_key}"), first: 1) @cascade {{
                    uid,
                    node_type: dgraph.type,
                    {node_key_prop},
                    {prop_name}
                }}
            
            }}
        """

        txn = self.dgraph_client.txn(read_only=True)
        try:
            res = json.loads(txn.query(query).json)
        finally:
            txn.discard()
        raw_prop = res["res"]
        if not raw_prop:
            return None
        if isinstance(raw_prop, list):
            raw_prop = raw_prop[0]

        if raw_prop.get(prop_name) is None:
            return None

        prop = prop_type(raw_prop[prop_name])
        if isinstance(prop, str):
            return unescape_dgraph_str(prop)
        return prop
Ejemplo n.º 3
0
    def from_dict(cls: Type["NV"], dgraph_client: DgraphClient,
                  d: Dict[str, Any]) -> "NV":
        properties = {}
        node_type = d.get("node_type") or d.get("dgraph.type")
        if node_type:
            if isinstance(node_type, list):
                if len(node_type) > 1:
                    # TODO: This is a hack, workaround for a preexisting bug where some nodes are labeled as Risk
                    node_type = [nt for nt in node_type if nt != "Risk"]

                    if len(node_type) > 1:
                        print(
                            f"WARN: Node has multiple types: {node_type}, narrowing to: {node_type[0]}"
                        )

                node_type = node_type[0]
            properties["node_type"] = node_type
        else:
            print(
                f"WARN: Node is missing type: {d.get('node_key', d.get('uid'))}"
            )

        for prop, into in cls._get_property_types().items():
            val = d.get(prop)

            if val or val == 0:
                if into == str:
                    val = unescape_dgraph_str(str(val))
                elif into == int:
                    val = int(val)
                properties[prop] = val

        edges = {}  # type: Dict[str, Union[Viewable, List[Viewable]]]
        for edge_tuple in cls.get_edge_types().items():
            edge_name = edge_tuple[0]  # type: str
            forward_name = None  # type: Optional[str]
            if isinstance(edge_tuple[1], tuple):
                ty = edge_tuple[1][0]  # type: EdgeViewT
                forward_name = edge_tuple[1][1]
            else:
                ty = edge_tuple[1]

            raw_edge = d.get(edge_name, None)

            if not raw_edge:
                continue

            if isinstance(ty, List):
                ty = ty[0]

                if d.get(edge_name, None):
                    f_edge = d[edge_name]
                    if isinstance(f_edge, list):
                        _edges = [
                            ty.from_dict(dgraph_client, f) for f in f_edge
                        ]
                    elif isinstance(f_edge, dict):
                        _edges = [ty.from_dict(dgraph_client, f_edge)]
                    else:
                        raise TypeError(
                            f"Edge {edge_name} must be list or dict")

                    if forward_name:
                        edges[forward_name] = _edges
                    else:
                        edges[edge_name] = _edges

            else:
                if isinstance(raw_edge, list):
                    edge = ty.from_dict(dgraph_client, raw_edge[0])
                elif isinstance(raw_edge, dict):
                    edge = ty.from_dict(dgraph_client, raw_edge)
                else:
                    raise TypeError(f"Edge {edge_name} must be list or dict")

                if forward_name:
                    edges[forward_name] = edge
                else:
                    edges[edge_name] = edge

        cleaned_edges = {}  # type: Dict[str, Union[Viewable, List[Viewable]]]
        for _edge in edges.items():
            edge_name = _edge[0]
            cleaned_edge = _edge[1]  # type: Union[Viewable, List[Viewable]]
            if edge_name[0] == "~":
                edge_name = edge_name[1:]
            cleaned_edges[edge_name] = cleaned_edge

        return cls(
            dgraph_client=dgraph_client,
            node_key=d["node_key"],
            uid=d["uid"],
            **properties,
            **cleaned_edges,
        )