diff --git a/src/caosadvancedtools/table_json_conversion/fill_xlsx.py b/src/caosadvancedtools/table_json_conversion/fill_xlsx.py index 62aa922a7f6fd863d6bb766ebb25ac5800dc7658..63c14af7ac92213e07c63408327a7004be9f7bec 100644 --- a/src/caosadvancedtools/table_json_conversion/fill_xlsx.py +++ b/src/caosadvancedtools/table_json_conversion/fill_xlsx.py @@ -262,6 +262,8 @@ out: union[dict, None] context = TemplateFiller.Context() context.fill_from_data(data) + explode_later: List[dict] = [] + insertables: Dict[str, Any] = {} for name, content in data.items(): path = current_path + [name] @@ -275,16 +277,23 @@ out: union[dict, None] if isinstance(content[0], dict): # An array of objects: must go into exploded sheet for entry in content: - self._handle_data(data=entry, current_path=path, context=next_context) + explode_later.append({"data": entry, "current_path": path, + "context": next_context}) continue elif isinstance(content, dict): if not current_path: # Special handling for top level - self._handle_data(content, current_path=path, context=next_context) + explode_later.append({"data": content, "current_path": path, + "context": next_context}) continue insert = self._handle_data(content, current_path=path, context=next_context.copy(), only_collect_insertables=True) assert isinstance(insert, dict) assert not any(key in insertables for key in insert) + + # print(insert) + # from IPython import embed + # embed() + insertables.update(insert) continue else: # scalars @@ -301,8 +310,9 @@ out: union[dict, None] insertables[path_str] = value if only_collect_insertables: return insertables - if not current_path: - return None + # if not current_path: + # print("returning early") + # return None # actual data insertion insert_row = None @@ -318,11 +328,21 @@ out: union[dict, None] sheet.cell(row=insert_row+1, column=col_index+1, value=value) + # continue in exploded sheets + for exploded_content in explode_later: + print(f"Exploding: {exploded_content}") + self._handle_data(**exploded_content) + # Insert foreign keys if insert_row is not None and sheet is not None and _is_exploded_sheet(sheet): foreigns = _get_foreign_key_columns(sheet) for index, path in ((f.index, f.path) for f in foreigns.values()): - value = context[path] + try: + value = context[path] + except KeyError as err: + print(f"\nCurrent context: {context._props}") + from IPython import embed + embed() sheet.cell(row=insert_row+1, column=index+1, value=value) return None diff --git a/unittests/table_json_conversion/data/indirect_data.xlsx b/unittests/table_json_conversion/data/indirect_data.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..45ed38b8222d105f1958cef6a41c12d42a49c883 Binary files /dev/null and b/unittests/table_json_conversion/data/indirect_data.xlsx differ diff --git a/unittests/table_json_conversion/test_fill_xlsx.py b/unittests/table_json_conversion/test_fill_xlsx.py index 4af73e4d2125d05c4379bd88c618ae27545d5221..1dec84943286b90424aa7817bff4739b787d0822 100644 --- a/unittests/table_json_conversion/test_fill_xlsx.py +++ b/unittests/table_json_conversion/test_fill_xlsx.py @@ -78,10 +78,16 @@ def test_fill_xlsx(): template_file=rfp("data/multiple_refs_template.xlsx"), known_good=rfp("data/multiple_refs_data.xlsx"), schema=rfp("data/multiple_refs_schema.json")) + + +def test_fill_indirect_reference(): + # Run this test: + # pytest --pdb --pdbcls=IPython.terminal.debugger:Pdb test_fill_xlsx.py::test_fill_indirect_reference -s fill_and_compare(json_file=rfp("data/indirect_data.json"), template_file=rfp("data/indirect_template.xlsx"), - known_good=rfp("data/multiple_refs_data.xlsx"), - schema=rfp("data/indirect_schema.json")) + known_good=rfp("data/indirect_data.xlsx"), + schema=rfp("data/indirect_schema.json"), + custom_output=rfp("data/indirect_data.xlsx")) def test_errors():