Skip to content

Bulk Coach Assignment: Optimize creation w/ bulk_create if possible #13657

@nucleogenesis

Description

@nucleogenesis

This issue is not open for contribution. Visit Contributing guidelines to learn about the contributing process and how to find suitable issues.

Observed behavior

In #13614 the RoleListSerializer class iterates over it's validated data and saves them individually w/ a get_or_create() method call. There is a bulk_create() method available, but it did not work out of the box for our case.

Errors and logs

@ozer550 had this code:

class RoleListSerializer(serializers.ListSerializer):
    def create(self, validated_data):
        ModelClass = self.child.Meta.model
        objects_to_create = []
        for model_data in validated_data:
            self.child.changes = []
            object_to_create = self.child.create(model_data)
            objects_to_create.append(object_to_create)
            self.changes.extend(self.child.changes)
        try:
            created_objects = ModelClass._default_manager.bulk_create(
                objects_to_create, ignore_conflicts=True
            )
        except TypeError:
            tb = traceback.format_exc()
            msg = (
                "Got a `TypeError` when calling `%s.%s.create()`. "
                "This may be because you have a writable field on the "
                "serializer class that is not a valid argument to "
                "`%s.%s.create()`. You may need to make the field "
                "read-only, or override the %s.create() method to handle "
                "this correctly.\nOriginal exception was:\n %s"
                % (
                    ModelClass.__name__,
                    ModelClass._default_manager.name,
                    ModelClass.__name__,
                    ModelClass._default_manager.name,
                    self.__class__.__name__,
                    tb,
                )
            )
            raise TypeError(msg)
        return created_objects

and ran into this error (gist to save space here)

Expected behavior

See the thread here and take note of the "caveats" section in the docs for bulk_create.

Also bear this in mind:

@rtibbles: I agree that this may be something specific for morango models. My guess is that the id is not being set properly during bulk create. Ideally we would be able to use bulk_create with ignore_conflicts=True here to optimize the querying.

Steps to reproduce

  1. Apply the code snippet above to the kolibri.core.auth.serializers.RoleListSerializer class
  2. In Facility -> Users select several coaches and assign them to classes
  3. Investigate whether the errors seen here can be overcome so that we can leverage the optimized bulk creation method.

Metadata

Metadata

Assignees

Labels

DEV: backendPython, databases, networking, filesystem...TAG: tech update / debtChange not visible to user

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions