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

update nested object #1573

Open
venelin-mihaylov opened this issue Feb 7, 2019 · 64 comments
Open

update nested object #1573

venelin-mihaylov opened this issue Feb 7, 2019 · 64 comments
Assignees
Labels
a/api/graphql c/server Related to server k/enhancement New feature or improve an existing feature p/high candidate for being included in the upcoming sprint s/triaged This has been reviewed by Hasura t/native-dbs triage/4-rfc-published The RFC is published and comments are requested

Comments

@venelin-mihaylov
Copy link

venelin-mihaylov commented Feb 7, 2019

First, thank you very much for your work on Hasura, its a great product.
There is a feature that I would be very happy to have, wanted to know what are your thoughts on it.
Currently there Is a nested insert feature. However having only an insert without update is not very useful.

Do you have plans to implement update for nested objects?
IMO, the logic would have to be:
I. for lists (1:N)

  • for every relation record:
    1. If it is present in input, not present in the db, then insert the record and link it to owning record
    2. If it is present in db, not present in input, the delete it
    3. If it is present in db and is present in input, then update its columns

II. For objects (belongsTo)

  • if relation record has an ID, link it to master and update its values
  • if relation record has no ID, then create it
  • if relation record is not present in input, but is present in db, then unlink it (an option to delete it would be nice)

Thank you

@shahidhk shahidhk added the c/server Related to server label Feb 8, 2019
@alaarihan
Copy link

alaarihan commented Feb 17, 2019

@venelin-mihaylov I have some notes about your suggestion:

I. for lists (1:N)

  • for every relation record:

    1. If it is present in input, not present in the db, then insert the record and link it to owning record
    2. If it is present in db, not present in input, the delete it

in your delete case we will always have to include all of the related object to avoid deleting them! what if we have a million items, we need to include all of them to the nested update mutation to avoid losing them? I think we need another way for delete nested items

  1. If it is present in db and is present in input, then update its columns

And we need a way to link existing items to the master without updating their data

II. For objects (belongsTo)

  • if relation record has an ID, link it to master and update its values
  • if relation record has no ID, then create it
  • if relation record is not present in input, but is present in db, then unlink it (an option to delete it would be nice)

Here is the same note too we can't delete all items when we don't include them in the nested mutation, we need to think in a different way.

@0x777 0x777 added the k/enhancement New feature or improve an existing feature label Apr 30, 2019
@anasvn
Copy link

anasvn commented May 14, 2019

Waiting for this feature to reduce multiple hasura calls.

@nolandg
Copy link

nolandg commented May 26, 2019

@alaarihan The way Prisma solves this is with a connect and a disconnect field so you don't need to include a million ids in your mutation request. eg:

updatePost(_set: {
  tags: {
    connect: [
      {id: 1},
      {id: 2},
    ],
    disconnect: [
      {id: 3},
      {id: 4}
    ],
    insert: [
      {name: "cats"}
    ],
  }
})

Anything not mentioned in these fields is not touched. User-land code must decide what is present in db already that needs removing etc. This makes more sense because since you're probably not adding/removing millions of things at once and you have a list of which ones you're changing. This works really well for me with Prisma. I'm trying to see how to convert my framework over to Hasura...will require some extra queries me thinks.

@alaarihan
Copy link

alaarihan commented May 27, 2019

Yes @nolandg , I'm familiar with Prisma system but if we made this change in Hasura that will cause a big breaking change to the system so I was thinking in a different way to make it without breaking changes if that possible.

@luke-j
Copy link

luke-j commented Jun 23, 2019

Curious if this is on the roadmap? This seems like a really important feature to have, in my opinion.

@bkstorm
Copy link

bkstorm commented Jul 14, 2019

yeah, it's inconvenient when hasura doesn't support this feature.
For example: a product can have a thumbnail (optional and is stored in image table), id of the thumbnail is stored in the field thumbnail_id in product table.
First, I create a product without the thumbnail. It's ok, very easy.
Then I want to add a thumbnail to the product.
I have to insert a new row into image table, get id back then update product table with that id.
And all the operation should be in the same transaction.
What should I do, using event trigger or create a new resolvers on my own graphql server.

@marionschleifer marionschleifer added the p/urgent Immediate action required label Jul 25, 2019
@marionschleifer marionschleifer assigned 0x777 and unassigned dsandip Jul 25, 2019
@RodolfoSilva
Copy link
Contributor

Any update about this issue?

@switz
Copy link

switz commented Sep 22, 2019

Also would be very interested in a feature like this 👍

@rille111
Copy link

Would be very interested. Right now I just delete all nested relations and then just loop through what changes are made and insert them all. Ugly but works.

@marionschleifer marionschleifer added the support/needs-action support ticket that requires action by team label Nov 20, 2019
@0x777 0x777 assigned rakeshkky and unassigned 0x777 Dec 2, 2019
@coco98 coco98 added triage/2-needs-rfc This feature needs to be spec'd out triage/3-rfc-wip RFC is being written and removed triage/2-needs-rfc This feature needs to be spec'd out labels Dec 19, 2019
@marionschleifer marionschleifer removed the support/needs-action support ticket that requires action by team label Dec 19, 2019
@heliocaruccio
Copy link

Hello developers. I'm in a part of development where it required a little bit of code dirt to perform nested updates. My question is whether this functionality will be developed and more or less when it might be made available to us. Depending on the case, I push certain features further.

@marionschleifer
Copy link
Contributor

@heliocaruccio we are in the process of working on a spec for this issue. It should be ready within a month. We'll be able to share new information then 🙂

@rille111
Copy link

@heliocaruccio we are in the process of working on a spec for this issue. It should be ready within a month. We'll be able to share new information then 🙂

Awesome! All love to the Hasura team. You make development with this tech fun.

@sejoalfaro
Copy link

Is there any news?

@rikinsk rikinsk mentioned this issue Feb 7, 2020
1 task
@marionschleifer marionschleifer removed the triage/3-rfc-wip RFC is being written label Feb 12, 2020
@rsd1122 rsd1122 assigned dameleney and unassigned 0x777 and rakeshkky Dec 6, 2022
@nathikazad
Copy link

Yes please, its a struggle without this. For every relation we need to make a mutation and then update

@beepsoft
Copy link

beepsoft commented Feb 9, 2023

@dameleney Is there any progress with the RFC and implementation?

Funny you mentioned graphjin (as an inspiration): they just seem to implemented transactions and they may have taken inspiration from an earlier Hasura RFC dosco/graphjin#411

By the way: it would be great to have transactions as well. :-)

@abdifardin
Copy link

I learned something important from Hasura.
You can raise $100 million and represent yourself as a big brand but still struggle to solve an issue for years.
This has given me motivation for my next startup. It's not that hard.
Thank you, Hasura.

FYI, Hasura v3 is coming... and this 4 years old issue is still open

@nathikazad
Copy link

Ya this is insane, @coco98 please take a look into this. Its been 4 years.

@beepsoft
Copy link

@dameleney just mentioned at the community call:

"We are actively researching how logical models (#7473) will help with some of the existing community feature requests such as enums, nested mutations, GroupBy, and more."

@PedroBern
Copy link
Contributor

PedroBern commented May 22, 2023

Currently, the most effective approach I have found to create a new object and set the relationship within an update mutation is to utilize multiple mutations in a single request.

mutation createFooAndUpdateBarByPK(
  $insert_object: foo_insert_input!
  $update_pk: uuid!
  $update_set: bar_set_input!
) {
  insert_foo_one(object: $insert_object) {
    id
    # Avoid requesting foo fields here as they may be outdated
    # (due to potential side effects on foo after linking it to bar)
  }
  # The "_set" field will include a reference to foo, such as foo_pk: "..."
  update_bar_by_pk(pk_columns: { pk: $pk }, _set: $update_set) {
   ...bar
   foo {
    ...foo # Request updated foo fields
   }
  }
}

@beepsoft
Copy link

@dameleney just mentioned at the community call:

"We are actively researching how logical models (#7473) will help with some of the existing community feature requests such as enums, nested mutations, GroupBy, and more."

@dameleney I just realized and was also confirmed at the last community call that logical models are only available in the Cloud and Enterprise edition. As the nested object update solution is planned to be based in logical models, it means that this feature won't be available in the community edition. Or am I missing something?

@manasag
Copy link
Contributor

manasag commented Jun 21, 2023

Hi @beepsoft, we have now made Logical Models available for community edition with v2.28 onwards.

@abdifardin
Copy link

Can anybody explain please how Logical Model will address the update nested object problem?

@beepsoft
Copy link

Hi @beepsoft, we have now made Logical Models available for community edition with v2.28 onwards.

Thanks, @manasag, great news! And I see that also native queries are now supported for CE as well.

@abdifardin
Copy link

abdifardin commented Jun 24, 2023

Can anybody explain please how Logical Model will address the update nested object problem?

After some research i got the answer

The Logical Model feature combined with Native Queries may potentially address nested updates. we can define a SQL query that performs the desired update operation on nested objects and expose this as a GraphQL mutation.

For example, if we have a one-to-many relation from authors to posts, we can write a SQL query to update an author and their related posts, and expose this through Hasura's Native Queries.

But, we should note that as of now, only read-only queries are supported.
Future updates might allow mutations.

@manasag
Copy link
Contributor

manasag commented Jun 26, 2023

Yes, and I apologise for confusion from Hasura side. Logical Models (launched and available in CE in v2.2.8) currently only support queries and not mutations. Nested update can be solved once we support mutations with Logical Models. We have this in our roadmap; thanks for being patient on this issue.

@cbsmith402
Copy link

Currently, the most effective approach I have found to create a new object and set the relationship within an update mutation is to utilize multiple mutations in a single request.

mutation createFooAndUpdateBarByPK(
  $insert_object: foo_insert_input!
  $update_pk: uuid!
  $update_set: bar_set_input!
) {
  insert_foo_one(object: $insert_object) {
    id
    # Avoid requesting foo fields here as they may be outdated
    # (due to potential side effects on foo after linking it to bar)
  }
  # The "_set" field will include a reference to foo, such as foo_pk: "..."
  update_bar_by_pk(pk_columns: { pk: $pk }, _set: $update_set) {
   ...bar
   foo {
    ...foo # Request updated foo fields
   }
  }
}

@PedroBern Can you elaborate on this solution a bit? Are you saying that somehow the result of insert_foo_one is available to the update_bar_by_pk mutation?

@PedroBern
Copy link
Contributor

@PedroBern Can you elaborate on this solution a bit? Are you saying that somehow the result of insert_foo_one is available to the update_bar_by_pk mutation?

@cbsmith402 yes of course.

The mutations are executed in sequence, so yes, the result of the first mutation is already present in the database when the second one is executed.

In my example:

  • The first mutation inserts foo
  • The second mutation sets the relationship between foo and bar

Note that you must know the primary key of foo before inserting it, in order to link it to bar on a single request (or better say, on a single db transaction), see the updated code below:

mutation createFooAndUpdateBarByPK(
  $foo_pk: uuid!
  $bar_pk: uuid!
) {
  # create foo
  insert_foo_one(object: {pk: $foo_pk}) {
    pk
  }
  # link foo and bar + request bar with related foo
  update_bar_by_pk(pk_columns: { pk: $bar_pk }, _set: { foo_pk: $foo_pk }) {
   ...bar
   foo {
    ...foo
   }
  }
}

@cbsmith402
Copy link

Note that you must know the primary key of foo before inserting it, in order to link it to bar on a single request (or better say, on a single db transaction)

Ah, yep, I came to the same conclusion (UUIDs for the win!). Just wanted to make sure I wasn't missing something.

@jdgamble555
Copy link

Is this still not possible in 2024?

J

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
a/api/graphql c/server Related to server k/enhancement New feature or improve an existing feature p/high candidate for being included in the upcoming sprint s/triaged This has been reviewed by Hasura t/native-dbs triage/4-rfc-published The RFC is published and comments are requested
Projects
None yet
Development

No branches or pull requests