def _collect_emb_file_ref(self, doc: dict, request_key: str) -> list: """ emb構造のデータからファイルリファレンスのリストだけを取り出すジェネレータ :param dict doc: :param str request_key: :return: value :rtype: list """ for key, value in doc.items(): if isinstance(value, dict): yield from self._collect_emb_file_ref(value, request_key) elif isinstance(value, list) and Utils.item_literal_check(value): if key == request_key: yield value continue elif isinstance(value, list): if key == request_key: yield value else: for i in value: yield from self._collect_emb_file_ref(i, request_key) else: continue
def child_delete(doc_with_child: dict) -> None: """ 子要素を削除する :param dict doc_with_child: :return: """ tmp = copy.deepcopy(doc_with_child) tmp_list = [] # 子要素のデータを抽出 for k, v in doc_with_child.items(): if self.parent != k and self.child != k and (isinstance( v, dict) or (isinstance(v, list) and (not Utils.item_literal_check(v)))): tmp_list.append(k) # 該当データがtmpにあれば削除 for j in tmp_list: if j in tmp: del tmp[j] # outputのデータを入れ替える if collection in output: output[collection].append(tmp) else: output[collection] = [tmp]
def _get_child_reference(self, child_data: dict) -> dict: """ 子データのリファレンス情報を作成して取得 :param dict child_data: :return: :rtype: dict """ children = [] for collection, child_value in child_data.items(): # すでにparentが作られている場合は飛ばす if self.parent == collection: continue if isinstance(child_value, dict): children.append(DBRef(collection, child_value['_id'])) elif isinstance( child_value, list) and (not Utils.item_literal_check(child_value)): child_list = [DBRef(collection, j['_id']) for j in child_value] children.extend(child_list) else: continue return {self.child: children}
def test__item_literal_check(self): # 正常系 リスト内が全てリテラルデータ data = [1, 2, 3] self.assertTrue(Utils.item_literal_check(data)) # 正常系 リスト内にオブジェクトを含むリテラルデータ data = [1, 2, ObjectId()] self.assertTrue(Utils.item_literal_check(data)) # 正常系 リスト内に辞書 data = [1, 2, {'d': 'bb'}] self.assertFalse(Utils.item_literal_check(data)) # 正常系 リスト内にリスト data = [1, 2, ['1', 2]] self.assertFalse(Utils.item_literal_check(data)) # 正常系 入力が辞書 data = {'d': '34'} self.assertFalse(Utils.item_literal_check(data))
def recursive(data: dict): # idとrefの削除 for key, val in data.items(): if isinstance(data[key], dict): recursive(Utils.reference_item_delete(data[key], refs)) # リストデータは中身を型変換する elif isinstance(data[key], list) and Utils.item_literal_check( data[key]): data[key] = [self._format_datetime(i) for i in data[key]] elif isinstance(data[key], list): for item in data[key]: recursive(Utils.reference_item_delete(item, refs)) else: try: # 型変換 data[key] = self._format_datetime(data[key]) except Exception as e: sys.exit(e)
def recursive(doc): output = {} for key, value in doc.items(): if isinstance(value, dict): if key in ex_keys: continue output.update({key: recursive(value)}) elif isinstance(value, list) and Utils.item_literal_check(value): output.update({key: value}) elif isinstance(value, list): if key in ex_keys: continue output.update({key: [recursive(i) for i in value]}) else: output.update({key: value}) return output
def recursive(data): for key, value in data.items(): if isinstance(value, dict): for del_key in reference: if del_key in value: del value[del_key] recursive(value) elif isinstance(value, list) and Utils.item_literal_check( value): continue elif isinstance(value, list): for i in value: for del_key in reference: if del_key in i: del i[del_key] recursive(i) else: pass
def recursive(data: dict) -> dict: """ 再帰で辞書を走査して、日付データの変換などを行う 要リファクタリング :param dict data: :return: :rtype: dict """ output = {} for key, value in data.items(): if isinstance(value, dict): if not Utils.collection_name_check(key): sys.exit(f'この名前は使用できません {key}') converted_value = self._convert_datetime(value) output.update({key: recursive(converted_value)}) elif isinstance(value, list): # 日付データが含まれていたらdatetimeオブジェクトに変換 value = self._date_replace(value) # 通常のリストデータの場合 if Utils.item_literal_check(value): if not self._field_name_check(key): sys.exit(f'フィールド名に不備があります {key}') list_tmp_data = value # 子要素としてのリストデータの場合 else: if not Utils.collection_name_check(key): sys.exit(f'この名前は使用できません {key}') list_tmp_data = [ recursive(self._convert_datetime(i)) for i in value ] output.update({key: list_tmp_data}) else: if not self._field_name_check(key): sys.exit(f'フィールド名に不備があります {key}') output.update({key: value}) return output
def _merge(self, orig: dict, amend: dict) -> dict: """ 辞書(オリジナル)と修正データをマージする :param dict orig: :param dict amend: :return: result :rtype: dict """ result = copy.copy(orig) for item in amend: if isinstance(amend[item], dict): result[item] = self._merge(orig[item], amend[item]) elif isinstance(amend[item], list): if Utils.item_literal_check(amend[item]): result[item] = amend[item] else: result[item] = self._merge_list(orig[item], amend[item]) else: result[item] = amend[item] return result
def recursive(doc): for key, value in doc.items(): # 最初に発見した要素がoutputに入っていたら再帰を終了 if output: break if isinstance(value, dict): if key == pull_key: output.update({key: value}) recursive(value) elif isinstance(value, list) and Utils.item_literal_check(value): pass elif isinstance(value, list): if key == pull_key: output.update({key: value}) tmp_list = [] for i in value: tmp_list.append(recursive(i)) else: pass
def recursive(reading_dict_data: dict) -> dict: """ edman用に変換を行う 再帰 要リファクタリング :param dict reading_dict_data: :return: output :rtype: dict """ output = {} parent = -2 # 説明変数 my = -1 # 説明変数 for key, value in reading_dict_data.items(): if isinstance(value, dict): if not Utils.collection_name_check(key): sys.exit(f'この名前はコレクション名にできません {key}') # リファレンス作成 ref_list.append(DBRef(key, ObjectId())) # tmpから子データが返ってくる tmp = recursive(self._convert_datetime(value)) # 親のリファレンス(コレクション)を追加 # rootの場合は追加されない if len(ref_list) > 1: tmp.update({self.parent: ref_list[parent]}) # 子データのリファレンスを取得して親のデータに入れる child_ref = self._get_child_reference(tmp) if list(child_ref.values())[0]: # 子データがない場合もある tmp.update(child_ref) # self.parentがない場合(=root)の場合にoidを追加する if self.parent not in tmp: tmp.update({'_id': ref_list[0].id}) del ref_list[my] # バルクインサート用のリストを作成 list_output.append(self._list_intercept_hook(key, tmp)) output.update({key: tmp}) elif isinstance(value, list) and Utils.item_literal_check(value): if not self._field_name_check(key): sys.exit(f'フィールド名に不備があります {key}') # 日付データが含まれていたらdatetimeオブジェクトに変換 output.update({key: self._date_replace(value)}) elif isinstance(value, list): if not Utils.collection_name_check(key): sys.exit(f'この名前はコレクション名にできません {key}') tmp_list = [] for i in value: # リファレンス作成 ref_list.append(DBRef(key, ObjectId())) # tmpから子データが返ってくる tmp = recursive(self._convert_datetime(i)) # 親のリファレンス(コレクション)を追加 # rootの場合は追加されない if len(ref_list) > 1: tmp.update({self.parent: ref_list[parent]}) # 子要素だけのデータの場合else区へ飛ばないのでここでoidを作成する if '_id' not in tmp: tmp.update({'_id': ref_list[my].id}) # 子データのリファレンスを取得して親のデータに入れる child_ref = self._get_child_reference(tmp) if list(child_ref.values())[0]: # 子データがない場合もある tmp.update(child_ref) del ref_list[my] tmp_list.append(tmp) # バルクインサート用のリストを作成 list_output.append(self._list_intercept_hook( key, tmp_list)) output.update({key: tmp_list}) else: if not self._field_name_check(key): sys.exit(f'フィールド名に不備があります {key}') # oidを取得して追加(rootの場合、すでに作成されている場合がある?) if '_id' not in output: output.update({'_id': ref_list[my].id}) output.update({key: value}) return output