strawberry-graphql / strawberry-django

Strawberry GraphQL Django extension
MIT License
394 stars 115 forks source link

Updating related objects with `unique_together` including the FK raises IntegrityError #360

Closed zvyn closed 10 months ago

zvyn commented 10 months ago

Consider the following setup:

class Parent(models.Model):
    pass

class Child(models.Model):
    name = models.CharField()
    parent = models.ForeignKey(Parent, on_delete=models.CASCADE, related_name="children")

    class Meta:
        unique_togetehr = [("name", "parent")]

@strawberry_django.input(Child)
class ChildInput:
    name: auto

class ParentType:
    id: auto

@strawberry_django.input(Parent)
class ParentInput:
    children = Optional[list[ChildInput]]

@strawberry.type
class Mutation:
    update_parent: ParentType = strawberry_django.mutations.create(types.ParentInput)

Assuming a Parent with ID 1 but no child exists this works on the first attempt only:

mutation {
  updateParent(data: {id: 1, children: [{name: "foo"}]}) {
    id
  }
}

On the second attempt an error is raised:

django.db.utils.IntegrityError: duplicate key value violates unique constraint "child_parent_id_name_12345678_uniq"

This is due to the update_m2m creating new objects, even if the data is uniquely identifying an existing relation.

Proposed solution: Use manager.get_or_create instead of manager.create.

Upvote & Fund

Fund with Polar