When running an upsert operation with 1 mutation or more, each having conditions, is there a way to know if a mutation has been successfully executed or not ?
MichelDiz
(Michel Diz)
September 8, 2020, 5:07pm
2
In the body result you have few keys that might help you.
{
"data": {
"q": [],
"code": "Success",
"message": "Done",
"uids": {
"uid(v)": "0x1"
}
},
"extensions": {...}
}
If it creates a new node, the UID from it will appear in the "uids" key.
If it just upsert, it will appear in the "q" key (this key is your query). And the "uids" key will be empty.
Make sure that you don’t use var block in the main query that you need information.
I have some tickets opened about implementing better contextual information about the Upsert Block. But for now, that’s what you got.
Cheers.
I don’t recognize this response format, how do you obtain it ?
n.b I work primarily with the nodejs client
MichelDiz
(Michel Diz)
September 8, 2020, 5:23pm
4
My guess (I can look later) is:
const response = await txn.mutate(mu);
await txn.commit();
console.log(response);
The api is a bit different, you can do response.getUidsMap() to get assigned uid to new nodes and response.getJson() will give you the payload of the query(ies) you ran.
But re-reading your original reply, I realize that you were referring to the data produce by the two functions I mentioned. And as such what you describe is what I’m already doing.
It gets complicated when performing upserts on multiple entities within the same operation however.
Thanks for your reply anyways
Any chance you could link to some of those tickets, so that I could track the advancement ?
MichelDiz
(Michel Diz)
September 8, 2020, 6:53pm
6
This one
opened 08:13PM - 23 Sep 19 UTC
closed 06:20PM - 23 Jan 20 UTC
kind/enhancement
priority/P2
status/needs-specs
area/upsert
## Experience Report
### What you wanted to do
I would like to execute Ups… erts transactions and have a logical response from what is happening. Sometimes we send a transaction that does not return contextual information about the transaction itself. We only have some information when the transaction creates a new object in the DB. But it's not human-friendly.
### Why that wasn't great, with examples
For example, if I want to bind two entities in one Upsert. I will get a "Success" + "Done" code and an empty "uids" field. This information does not help me debug what is happening. I know there was writing because I can check directly by making a new query.
```js
{
data: { code: 'Success', message: 'Done', uids: {} },
extensions: {
server_latency: { parsing_ns: 73769, processing_ns: 5960909 },
txn: { start_ts: 653, commit_ts: 654 }
}
}
```
What we need is something like (That would be just a sketching idea, certainly should follow established standards/patterns):
If the user sends an upsert and there was a writing in Dgraph.
```js
{
data: { code: 'Success', recorded: 'true', message: 'Done', uids: { 'uid(USER)': '0x5092d' } }
//(...)
}
```
If the user sends an upsert and there was no writing in Dgraph.
```js
{
data: { code: 'Success', recorded: 'false', message: 'Done', uids: {} }
//(...)
}
```
Now let's say I use "cond()" on a mutation. I have no information about the context of this condition when performed. Whether it wrote it or not. Let's say my cond is "@if (NOT eq (len (USER), 1))" - ie it will only write if the value is zero. This happens without the dev/user being aware of what is happening.
In the Cond hypothesis, it would be ideal to return values confirming or not the writing.
If the user sends an upsert with a condition (`@if(NOT eq(len(USER), 1))`) and there was a writing in Dgraph.
>In this case, we assume that the result of the condition was "found no user". Since the condition proposal matches the result then the answer is "cond: 'true'".
```js
{
data: { code: 'Success', recorded: 'true', message: 'Done', uids: { 'uid(USER)': '0x5092d' }, cond: 'true' }
//(...)
}
```
>In the case of multiple conditions (as it would be in the case of multiple mutations), then each new condition would have to have a field of its own. e.g. `cond0: 'true', cond1: 'false', cond2: 'true',`
>Maybe
>```
>cond: {0: 'true', 1: 'false', 2: 'true'},
>```
>named mutations
>```
>cond: { "userMutation": 'true', "schoolEnroll": 'false', "inSelection": 'true'},
>```
Closed in favor of Support return response after the Upsert Block done. (Like GraphQL does) · Issue #4653 · dgraph-io/dgraph · GitHub
Which is Support return response after the Upsert Block done. (Like GraphQL does) - Dgraph - Discuss Dgraph
And this one
opened 05:44PM - 27 Apr 20 UTC
closed 02:19AM - 11 Aug 24 UTC
kind/enhancement
status/accepted
area/usability
area/upsert
dgraph
Stale
## Experience Report
> This could be useful to create error UI instead of a J… SON response.
### What you wanted to do
An upsert mutation.
The error model we currently have can be bad to read when making big queries. There are users (mainly customers) who make huge queries with many variables. The error message can get big and confusing. In addition to containing characters that hinder reading.
### What you actually did
A wrong upsert block
```
upsert {
query {
me(func: eq(email, "user@company1.io")) {
u as uid
n as name
a as age
e as email
}
}
mutation @if(eq(n, "Animesh")) {
set {
_:newNode <name> val(name) .
_:newNode <age> val(age) .
_:newNode <email> val(email) .
}
}
}
```
### Why that wasn't great, with examples
##### This error is bad for some cases.
```
{
"name": "t",
"url": "http://localhost:8080/mutate?commitNow=true",
"errors": [
{
"message": "Some variables are defined but not used\nDefined:[__dgraph__0 a e n u]\nUsed:[__dgraph__0 age email name]\n",
"extensions": {
"code": "ErrorInvalidRequest"
}
}
]
}
```
#### The answer should be something like
```
{
"name": "t",
"url": "http://localhost:8080/mutate?commitNow=true",
"errors": [
{
"message": "Some variables are defined but not used",
"Defined": "a e n u",
"Used": "age email name",
"extensions": {
"code": "ErrorInvalidRequest"
}
}
]
}
```
Or something similar to
```
{
"name": "t",
"url": "http://localhost:8080/mutate?commitNow=true",
"errors": [
{
"message": "Some variables are defined but not use",
"Details": {
"Defined": "a e n u",
"Used": "age email name"
},
"extensions": {
"code": "ErrorInvalidRequest"
}
}
]
}
```
Which is
1 Like
chewxy
(chewxy)
September 8, 2020, 7:04pm
7
This is what you would get out of Ratel. Your client library may already abstract away the things.
1 Like