def from_json(self, data: str) -> Dict[str, List[Any]]: """ Create rows from json string. """ data = jloads(data) table_data = {} root = self.table_path if self.orient == Orient.Records: data_rows = [ row_node.current_value for row_node in JPath.parse_str(root).match(data) ] for column_name, column_def in self.schema.items(): column_target = column_def.target column_type = column_def.type target_matcher = JPath.parse_str(column_target) col: List[Any] = [] for data_row in data_rows: maybe_cell_value = [ m.current_value for m in target_matcher.match(data_row) ] if not maybe_cell_value: # If no match col.append(None) elif len( maybe_cell_value) == 1 and column_type != "object": (cell_value, ) = maybe_cell_value if cell_value is not None: # Even we have value matched, # the value might be None so we don't do type conversion. cell_value = _TYPE_MAPPING[column_type](cell_value) col.append(cell_value) else: assert ( column_type == "object" ), f"{column_name}: {maybe_cell_value} is not {column_type}" col.append(maybe_cell_value) table_data[column_name] = col else: # TODO: split orient raise NotImplementedError return table_data
def _load(self): factions_jpath = JPath.parse_str("$.pilots.*.faction") _factions = [m.current_value for m in factions_jpath.match(manifest)] for pilot in manifest["pilots"]: _faction = Faction.load_data(pilot["faction"]) self.factions.append(_faction) for ship in pilot["ships"]: with open(PurePath(_local_path, ship).as_posix(), "r") as f: ship_data = json.load(f) _ship = Ship.load_data(ship_data) _ship.faction = _faction self.ships.append(_ship) for pilot_data in ship_data["pilots"]: _pilot = Pilot.load_data(pilot_data) _pilot.__setattr__("faction", _faction) _pilot.__setattr__("ship", _ship) self.pilots.append(_pilot) self.actions = _load_complex_manifest_data(Actions, "actions") self.conditions = _load_simple_manifest_data(Conditions, "conditions") self.damage_deck = _load_complex_manifest_data(DamageDeck, "damagedecks", "cards") self.stats = _load_complex_manifest_data(ShipStats, "stats") self.upgrades = _load_complex_manifest_data(Upgrades, "upgrades")
def jp2_query(json_to_query, query_expression): jp2_expr = Path.parse_str(query_expression) value_list = list() node_jsonpath_list = list() for m in jp2_expr.match(json_to_query): value_list.append(m.current_value) node_jsonpath_list.append(m.node.tojsonpath()) return value_list, node_jsonpath_list
def json_match(path, contents): if isinstance(path, str): return [m for m in Path.parse_str(path).match(contents)] else: return [m for m in path.match(contents)]
def json_parse(path: str): return Path.parse_str(path)
def json_get(path, contents): """Retrieve elements specified by path in contents""" return [m.current_value for m in json_match(path, contents)] def json_match(path, contents): if isinstance(path, str): return [m for m in Path.parse_str(path).match(contents)] else: return [m for m in path.match(contents)] if __name__ == "__main__": import copy from csi.twin.orm import DataBase x = Path.parse_str( "$..[?(@.data and @.label and @.entries().length() = 2)]") db = DataBase("../tests/fixtures/csi-large.db") for e in sorted(db.messages(), key=lambda m: m["unix_toi"]): print(json_get(str(x), e)) f = copy.deepcopy(e) print(f) json_transform(str(x), f, lambda d: d["data"]) print(f) f = copy.deepcopy(e) print(f) json_remove(str(x), f) print(f) break