prisma / prisma1

💾 Database Tools incl. ORM, Migrations and Admin UI (Postgres, MySQL & MongoDB) [deprecated]
https://v1.prisma.io/docs/
Apache License 2.0
16.54k stars 863 forks source link

Nested update mutations #127

Closed marktani closed 6 years ago

marktani commented 7 years ago

Append or Replace for to-many update mutations

mutation {
  updateConversation(
    id: "<id>", messages: [{
    text: "text",
  }]) {
    id
    messages {
      text
    }
  }
}

replaces messages of the conversation - would be cool if we have the chance to specify whether we want to replace or append instead. We could use messages_set and messages_push for example, or messages_append and messages_prepend.

Update related node for to-one update mutations

Desired behaviour:

updateAuthor(
  id: "xxx"
  user: {
    name: "Updated Name"
  }
) { 
  id
  user {
    id // unchanged
    name // Updated name
  }
}

Nested upserts for to-many relations

Allow upserting nested nods for to-many relations. This makes it easy to append new items and update existing ones at the same time.

lucfranken commented 7 years ago

The requested example:

Let's say you have a create/edit screen for an invoice.

The user works on the page on the client, can add / edit / delete invoice lines etc.

Then when he is done he hits save. (This complies for example in how iOS native works) try their contacts app. You can still cancel until ready. Only when saving the database gets an update.

I would suspect something like this to be possible:

mutation {
  updateOrCreateInvoice(
    id: "<id>", // When set: update invoice otherwise create
    client: {
      id: "<id>" // When set: update client otherwise create
      name: "Name of client"
    },
    lines: [
      {
        amount: 2,
        name: 'Product X',
        price: 5,
        total: 10
      },
      {
        amount: 5,
        name: 'Product X',
        price: 1,
        total: 5
      }
    ],
    total: 15
    ) {
    id
    total
    lines {
      id
      amount
      price
      total
    }
  }
}

It's rather implicit. In reality it would likely need an operator to decide whether to override the node in full or to update the fields.

For example the lines: If you already had 3 invoice lines (of which you removed one in the client) the third one should be deleted. That would need an explicit command.

All those changes need to happen at once (that's what the user submitted) like a transaction.


To add in a bit more context: In general (when working with React) you already store your state in a top level component. Let's say it's called Form.

That component already has the data, in the same structure as the graphql query needs. That's why it would be even more compelling to just push it down to the database and get everything sorted out there.

pugson commented 7 years ago

Any rough ETA for this? @marktani It would come in handy for my current project.

cameronk commented 7 years ago

Really interested in this, especially for to-one updates.

danmkent commented 7 years ago

It would be really good to be able to do an update mutation with nested mutations for related entities and have them either created or updated depending on whether an id is supplied for them.

In combination with cascading deletes for child entities no longer related to the parent, this would make it much easier to implement the common use case of a parent having a collection of children that make no sense independent of the parent.

marktani commented 6 years ago

Having non-model types as possible field types would be an alternative approach for 'nested upserts'. See https://www.graph.cool/forum/t/is-there-a-default-ordering-of-relations/1143/12?u=nilan and #308.

ghost commented 6 years ago

This mutation will replace the existing list of posts assigned to the author. If instead you want to append more posts to the list, you can modify the edge directly instead. I have the following but that is only querying the data. How do i actually append?

Also it seems like in order to append i first have to query for the generated id then am able to do this mutation. Is that correct? would love to just be able to update like how we add the first time.

mutation createTestResult { addToTestResults( automationTestTestId: "cjaa8isvd3bee0183ae0qjd1l" resultsAutomationResultId: "cjab8hqii0xo60129j5m5ednp" ) { automationTestTest { testId } resultsAutomationResult { qa } } }

sorenbs commented 6 years ago

Thanks for the input and patience everyone!

This is now being discussed in #1280 - please check it out and provide input if you believe the proposal can be improved.

nareshvarun commented 6 years ago

mutation{ createUserDetails( firstName:"naveen" secondName:"ramesh" mobileNum:"9678525895" email:"varun.g@stellentsoft.com" password:"123456"

cities:[
  {
  id:"cjakni4db45on0130fk249eko"
  }
]){
id
firstName
secondName
mobileNum
email
password

citieses{
  id
}
}

}

my requirement is to add citices id inthe array but not added please tell me any wrong