diff --git a/frappe/core/doctype/data_import/data_import.py b/frappe/core/doctype/data_import/data_import.py index 1c56f54303..7e8374a0a2 100644 --- a/frappe/core/doctype/data_import/data_import.py +++ b/frappe/core/doctype/data_import/data_import.py @@ -211,7 +211,12 @@ def export_json( doctype, path, filters=None, or_filters=None, name=None, order_by="creation asc" ): def post_process(out): - del_keys = ("modified_by", "creation", "owner", "idx") + # Note on Tree DocTypes: + # The tree structure is maintained in the database via the fields "lft" + # and "rgt". They are automatically set and kept up-to-date. Importing + # them would destroy any existing tree structure. For this reason they + # are not exported as well. + del_keys = ("modified_by", "creation", "owner", "idx", "lft", "rgt") for doc in out: for key in del_keys: if key in doc: diff --git a/frappe/modules/import_file.py b/frappe/modules/import_file.py index 5970eae5ca..fdfd00404c 100644 --- a/frappe/modules/import_file.py +++ b/frappe/modules/import_file.py @@ -107,6 +107,15 @@ def import_doc(docdict, force=False, data_import=False, pre_process=None, doc = frappe.get_doc(docdict) + # Note on Tree DocTypes: + # The tree structure is maintained in the database via the fields "lft" and + # "rgt". They are automatically set and kept up-to-date. Importing them + # would destroy any existing tree structure. + if getattr(doc.meta, 'is_tree', None) and any([doc.lft, doc.rgt]): + print('Ignoring values of `lft` and `rgt` for {} "{}"'.format(doc.doctype, doc.name)) + doc.lft = None + doc.rgt = None + doc.run_method("before_import") doc.flags.ignore_version = ignore_version