Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

NS_Node add_child does not properly manage caching + load_bulk results in AttributeError #307

Copy link
Copy link
@noaklick

Description

@noaklick
Issue body actions

Context
We are working on a project using treebeard's NS_Node implementation. We are building a system to recursively copy a folder structure into our database for tracking.

Issue
We found that recursively calling add_child resulted in an invalid tree data structure, with problems such as a child with multiple parents. After some digging, we discovered that this error was the result of a caching problem in add_child. We were able to implement a workaround for this bug by calling refresh_from_db() on the parent node before calling node.add_child().

We additionally attempted using the load_bulk function to see if this was an undocumented difference between add_child and load_bulk and found that this is a breaking bug for this function. load_bulk errors with
AttributeError: 'NoneType' object has no attribute '_cached_parent_obj'

Reproducible Example of load_bulk
To recreate the load_bulk issue on a model Folder(NS_Node):

new_root = Folder.add_root(name="new_root")
a_id = uuid.uuid4()
b_id = uuid.uuid4()
Folder.load_bulk([{"data": {"name": "a"}, "id": a_id, "children": [{"data": {"name": "b"}, "id": b_id}]}], new_root, True)

Reproducible Example of add_child
Given file structure:

A
 - B
 - C
   - File 1

We would expect to have three folders; A, children B and C. File 1 would be within Folder C. Instead, we see that C.get_parent() is B. Our implementation (with the workaround) is below:

def create_folders_and_files(tree, parent):
	parent.refresh_from_db() # THIS IS THE WORKAROUND
	new_folder = parent.add_child(name=tree['name'])
	for file, full_name in tree['files']:
		# create file within the folder you just made
	for folder in tree['folders']:
		create_folders_and_files(folder, new_folder)

create_folders_and_files(tree, root_node)
Noah-Houghton, kgbaldwin, kyfantaz and jbwar22

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      Morty Proxy This is a proxified and sanitized view of the page, visit original site.