@@ -533,19 +533,33 @@ def _pull_records(js: dict[str, Any], spec: list | str) -> list:
533
533
meta_vals : DefaultDict = defaultdict (list )
534
534
meta_keys = [sep .join (val ) for val in _meta ]
535
535
536
- def _recursive_extract (data , path , seen_meta , level : int = 0 ) -> None :
536
+ def _recursive_meta_extract (data , meta_remaining_path , meta_key , seen_meta ) -> None :
537
+ if isinstance (data , dict ):
538
+ if len (meta_remaining_path ) > 1 :
539
+ if meta_remaining_path [0 ] in data :
540
+ _recursive_meta_extract (data [meta_remaining_path [0 ]], meta_remaining_path [1 :], meta_key , seen_meta )
541
+ else :
542
+ if errors == "ignore" :
543
+ seen_meta [meta_key ] = np .nan
544
+ raise KeyError (f"SubKey { meta_remaining_path [0 ]} of key { meta_key } not found in meta data." )
545
+ else :
546
+ seen_meta [meta_key ] = _pull_field (data , meta_remaining_path [0 ])
547
+
548
+ def _recursive_extract (data , passed_path , remaining_path , seen_meta , level : int = 0 ) -> None :
537
549
if isinstance (data , dict ):
538
550
data = [data ]
539
- if len (path ) > 1 :
551
+ if len (remaining_path ) > 1 :
540
552
for obj in data :
541
553
for val , key in zip (_meta , meta_keys ):
542
- if level + 1 == len (val ):
554
+ if level + 1 == len (val ) and passed_path == val [: - 1 ] :
543
555
seen_meta [key ] = _pull_field (obj , val [- 1 ])
556
+ elif level + 1 < len (val ) and passed_path == val [:level ] and remaining_path [0 ] != val [level ]:
557
+ _recursive_meta_extract (obj , val [level :], key , seen_meta )
544
558
545
- _recursive_extract (obj [path [0 ]], path [1 :], seen_meta , level = level + 1 )
559
+ _recursive_extract (obj [remaining_path [0 ]], passed_path + remaining_path [: 1 ], remaining_path [1 :], seen_meta , level = level + 1 )
546
560
else :
547
561
for obj in data :
548
- recs = _pull_records (obj , path [0 ])
562
+ recs = _pull_records (obj , remaining_path [0 ])
549
563
recs = [
550
564
nested_to_record (r , sep = sep , max_level = max_level )
551
565
if isinstance (r , dict )
@@ -556,14 +570,14 @@ def _recursive_extract(data, path, seen_meta, level: int = 0) -> None:
556
570
# For repeating the metadata later
557
571
lengths .append (len (recs ))
558
572
for val , key in zip (_meta , meta_keys ):
559
- if level + 1 > len ( val ) :
573
+ if key in seen_meta :
560
574
meta_val = seen_meta [key ]
561
575
else :
562
576
meta_val = _pull_field (obj , val [level :])
563
577
meta_vals [key ].append (meta_val )
564
578
records .extend (recs )
565
579
566
- _recursive_extract (data , record_path , {}, level = 0 )
580
+ _recursive_extract (data , [], record_path , {}, level = 0 )
567
581
568
582
result = DataFrame (records )
569
583
0 commit comments