Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mutations - batch creation of objects

I want to use graphene to create many people in one go. The document only mention the way to create one person like this:

class CreatePerson(graphene.Mutation):
class Input:
    name = graphene.String()
    age = graphene.Int()

ok = graphene.Boolean()
person = graphene.Field(lambda: Person)

@staticmethod
def mutate(root, args, context, info):
    person = Person(name=args.get('name'), age=args.get('age'), mobile=args.get('mobile'))
    ok = True
    return CreatePerson(person=person, ok=ok)

are there any ways to get it done?

like image 926
Quy Tang Avatar asked May 19 '17 12:05

Quy Tang


People also ask

How the mutation fields are executed?

While query fields are executed in parallel, mutation fields run in series, one after the other. This means that if we send two updateAuthor mutations in one request, the first is guaranteed to finish before the second begins. This ensures that we don't end up with a race condition with ourselves.

What is Gql mutation?

Mutation queries modify data in the data store and returns a value. It can be used to insert, update, or delete data.

How are mutations used in React?

Executing a mutation To run a mutation, you first call useMutation within a React component and pass it a GraphQL string that represents the mutation. When your component renders, useMutation returns a tuple that includes: A mutate function that you can call at any time to execute the mutation.

What is the use of useMutation?

useMutation is a React hook provided by redux-query-react that can be used for easily making mutations from a React component.


4 Answers

Instead of using a mutation that creates a list of objects, you can also call a mutation that creates one objects multiple times in one GraphQL request. This is accomplished using GraphQL Aliases:

mutation {
  c001: createPerson(
    name: "Donald Duck"
    age: 42
  ) {
    id
  }

  c002: createPerson(
    name: "Daisy Duck"
    age: 43
  ) {
    id
  }

  c003: createPerson(
    name: "Mickey Mouse"
    age: 44
  ) {
    id
  }
}
like image 113
marktani Avatar answered Nov 23 '22 17:11

marktani


I can figure out a solution base on the answer of Jan Hančič

There is a type called graphene.InputObjectType to use in this case

The solution can be

class PersonInput(InputObjectType):
    name = graphene.String()
    age = graphene.Int()

class CreatePeople(graphene.Mutation):
    class Input:
       people = graphene.List(PersonInput)

    people = graphene.List(lambda: Person)

    @staticmethod
    def mutate(root, args, context, info):
        people = [Person.objects.create(name=person.name, age=person.age) for person in args.get('people')]
        return CreatePeople(people=people)
like image 23
Quy Tang Avatar answered Nov 23 '22 18:11

Quy Tang


Make your mutation input a list and return a list of created people. Something like this:

class CreatePerson(graphene.Mutation):
    class Input:
        name = graphene.List(graphene.String)

    ok = graphene.Boolean()
    people = graphene.List(Person)

    @staticmethod
    def mutate(root, args, context, info):
        people = [Person(name=name) for name in args.get('name)]
        ok = True
        return CreatePerson(people=people, ok=ok)
like image 25
Jan Hančič Avatar answered Nov 23 '22 18:11

Jan Hančič


Receive a list of input, create all instances and return them all

The model node/type should be like-

class UserType(DjangoObjectType):

    class Meta:
        model = User
        interfaces = (CustomGrapheneNode, )
        filter_fields = {}
        only_fields = (
            'name',
            'email'
        )

Define Input fields

class UserInput(graphene.InputObjectType):
    name = graphene.String(required=True)
    password = graphene.String(required=True)

Mutation class

class CreateUser(graphene.Mutation):
    users = graphene.List(UserType)

    class Input:
        data = graphene.List(UserInput)

    Output = graphene.List(UserType)

    def mutate(self, info, data):
        users = []
        for item in data:
            user = User.objects.create(name=data['name'], 
                                       password=data['password'])
            users.append(user)
        return users

make this mutation callable by main schema

class Mutation():
    create_user = CreateUser.Field()

the Mutation Query view will be as -

mutation{
    createUser(data:[{name:"john", password:"1234"},
                     {name:"john", password:"1234"}]) {
        user{
            name
        }
    }    
}
like image 23
hirok biswas Avatar answered Nov 23 '22 17:11

hirok biswas