Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The problem with duplicate nodes in same tree #80

Open
savao opened this issue Oct 19, 2022 · 0 comments
Open

The problem with duplicate nodes in same tree #80

savao opened this issue Oct 19, 2022 · 0 comments

Comments

@savao
Copy link

savao commented Oct 19, 2022

On our project, with numerous requests to api in a short time, they are processed in different threads. When a user requests the creation of several instances at once in a table that is inherited from MPTT, this occurs in such a way that the front-end sends several different requests to the back-end in a very short time, each of which calls the code for creating one instance of this table. These requests are processed in different threads. But an unpleasant situation arises, when processing in different threads, instances are assigned the same tree and the same left and right numbers for different table rows. As a result, it turns out that the tree has in the same node several different values ​​for this node.

Please help me to fix this problem. How we can deal with this problem?

models.py:

import sqlalchemy as sa
from sqlalchemy.orm import relationship
from sqlalchemy_mptt import BaseNestedSets

class UserFile(BaseNestedSets):
__tablename__ = "user_files"

id = sa.Column(sa.Integer, primary_key=True)
is_file: bool = sa.Column(sa.Boolean, default=False)
name: str = sa.Column(sa.String(100))
real_name: Optional[str] = sa.Column(sa.String(50))
size: int = sa.Column(sa.Integer, default=0)
downloaded_at: datetime = sa.Column(sa.DateTime, default=datetime.utcnow, nullable=False)
author_id = sa.Column("author_id", sa.ForeignKey("users.id", ondelete="CASCADE"), nullable=True)
author = relationship("User", foreign_keys=[self.author_id])

def __repr__(self) -> str:
    return self.name

schemas.py:

@spec_definition
class UserFileSchema(ModelSchema):
class Meta:
    model = UserFile
    fields = ["id", "name", "is_file", "size", "downloaded_at"]

views.py:

@api.resource("/user/<int:user_id>/files/root/add_file")
class UserFilesAddRootFileResource(SchemaResource):
    def post(self, user_id: int) -> dict:
        content = request.files.get("file")
        item = add_file(user_id, content, filename=content.filename)
        return UserFileSchema().dump(item)

user_files.py:

def add_file(user_id: int, content: FileStorage, filename: str) -> UserFile:
    size = file_size(content)
    final_name = storage.save(None, content, True)
    return add_user_file(
        user_id=user_id,
        name=filename,
        is_file=True,
        real_name=final_name,
        size=size,
    )

def add_user_file(
    user_id: int,
    name: str,
    real_name: Optional[str] = None,
    size: int = 0,
) -> UserFile:
    base_name = name
    if is_file:
        base_name, ext = storage.splitext(base_name)
    result_name = name
    item_id = None
item = UserFile(
    name=result_name,
    real_name=real_name,
    is_file=is_file,
    size=size,
    )
item.save()
return item

I am omitting the definition of some functions from the storage module, which are currently just a layer for working with the os.path.splitext(name) function or writing a file to disk, and they are not relevant to this problem.

I also wanted to ask why some tree nodes can have negative right and left numbers?

We use in our project Flask, SQLAlchemy, sqlalchemy-mptt==0.2.5

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant