Anyone have example of an upsert using python client and js object format?

I am using the Python DGraph client because I need to batch transactions atomically, and that’s the only way I can figure out how to do it.

I have figured out how to add/query, but I am looking at updating an object. I am looking at this comment as an example but I have been using the js object format and I’m not sure how I should be doing this.

For example, to add I have been doing this.

addState = {
  "uid" : "_:newNode",
  "State.num": 2001,
  "dgraph.type": "State"
}

txn = client.txn()
res = txn.mutate(set_obj=addState)
txn.commit()
txn.discard()

I want to update a state where the num = X and change some fields.

Looks like this is a new mutation. For upserts, you have to query for the UID created in the first mutation. Using Blank Nodes doesn’t work.

@docs do we have a complete example in the documentation of the python client(in the repo)?

I understand that, I was using it as an example of an “add”.

For example, to add I have been doing this.

It would be nice to have more documentation on using the Python client, as that is the only way I can seem to do atomic transactions (which are critical for DBs).

Hi @billybobthorton! Please take a look at the following documentation for upserts using the Dgraph Python client:

https://dgraph.io/docs/clients/python/#running-an-upsert-query--mutation

If this doesn’t answer your questions, let us know and we’ll get this topic updated.

Not having much luck and the two doc pages having different ways of doing it is confusing.

upsert = """{
  u as var(func: eq(id, "0x1fbd2"))
}"""
nquad = """
  uid(u) <prize> "15" .
"""

txn = client.txn()
try:
  mutation = txn.create_mutation(set_nquads=nquad)
  request = txn.create_request(query=upsert, mutations=[mutation], commit_now=False)
  print(txn.do_request(request))
  txn.commit()
except Exception as e:
  print(e)
finally:
  txn.discard()
  client_stub.close()

This is what I am running. It runs without errors, but nothing changes.

Then looking over the upsert block docs, I get a totally different way of doing it. I am using the JS Object format for adds and queries, but I don’t think I can do that with Upserts. Also, I have no idea what this nquads are.

curl -H "Content-Type: application/rdf" -X POST localhost:8080/mutate?commitNow=true -d $'
upsert {
  query {
    q(func: eq(email, "user@company1.io")) {
      v as uid
      name
    }
  }

  mutation {
    set {
      uid(v) <name> "first last" .
      uid(v) <email> "user@company1.io" .
    }
  }
}' | jq

I understand this is via Curl, but I am specifically referring to the upsert block syntax.

Why it is false?

Because I have a txn.commit() in there, and specifically because I want to do more than one transaction (some are not upserts) so I want to commit manually.

Would you mind testing with true? so then you can keep doing as you are doing. That would isolate possible issues related to handling a transaction manually.

Same issue. I’ve tried with auto commit and manual commit.

Weird, I’m not a Py dev. But looks like it is all good. Would mind changing the variable “upsert” to “query” instead? Maybe this creates a named object in the method. And when it runs it fails cuz it is expecting “query” instead.

I have done that as well, it was query initially but since it isn’t sent to the server (since it is a local python variable name) it won’t affect anything.

Well I have run the teamcity tests and it is running all fine. Check this test to compare with yours pydgraph/test_upsert_block.py at master · dgraph-io/pydgraph · GitHub

It might be some typo on your end. Which I can’t help even If I had direct access as I’m not a Py dev.

No luck, I am doing exactly as the tests do, and nothing.

Test code

    def test_one_mutation_one_query(self):
        txn = self.client.txn()
        mutation = txn.create_mutation(set_nquads='uid(u) <name> "Animesh" .')

        query = """
                {
                  me(func: eq(name, "Animesh")) {
                    u as uid
                  }
                }
                """

        request = txn.create_request(mutations=[mutation], query=query, commit_now=True)
        txn.do_request(request)

My code

query = """{
  query(func: eq(id, "0x1fbd2")){
    u as uid
  }
}"""

try:
  txn = client.txn()
  mutation = txn.create_mutation(set_nquads='uid(u) <prize> "15" .')
  request = txn.create_request(query=query, mutations=[mutation], commit_now=True)
  print(txn.do_request(request))
except Exception as e:
  print(e)
finally:
  txn.discard()
  client_stub.close()

Hey @billybobthorton,

Sorry about all the issues you’re facing. I really want to ensure that our documentation is top-notch. Would it be possible for you to jump on a call with @vvbalaji regarding the documentation issues you’re facing? It would help us improve the experience for you and for all the other folks who come after you.

Cheers,
Manish

2 Likes

Sure

Also having problems just doing the tour since the docker instructions don’t work.

I’m virtually at the point I’m ready to move on.

@billybobthorton: could you share your availability (if you prefer over email vvbalaji@dgraph.io) so that we can set up a call to understand and addres your pain points?

Sent you an email, thanks.

Hi @billybobthorton,

Can you share your GraphQL schema ? (specifically the type definition of node, 0x1fbd2 )
Is the predicate prize a field of some object in GraphQL schema ?

The prize predicate of the node won’t get affected if it is not part of the schema and the backend is being run in GraphQL mode.

By default, Slash GraphQL runs in GraphQL mode which does not allow adding predicate values which are not part of schema. You will have to use flexible mode to make changes to predicates using DQL.

You, may learn more about different Backend of modes of Slash over here, https://dgraph.io/docs/slash-graphql/admin/backend-modes/#flexible-mode/ .

Related Discuss Post: Some predicates are not being created on Slash .

Other reason for prize predicate not getting affected could be related to mapping of GraphQL and DQL predicates.

Consider this type in GraphQL schema,

type User {
    prize: String!
    name: String!
}

When this schema is applied, Dgraph internally creates 2 predicates with the name,
User.prize and User.name. The prize field is mapped to User.prize predicate in Dgraph.
In case, after inserting GraphQL schema, you want to perform some operations using DQL, you will have to use their Dgraph mappings, User.prize and User.name for these operations.

Do let us know if this solves your issue or if you face any other problems.

Relevant schema.

type Game  @withSubscription @auth(add: { rule: "{$ROLE: { eq: \"ADMIN\" } }"},
update: { rule: "{$ROLE: { eq: \"ADMIN\" } }"},
delete: { rule: "{$ROLE: { eq: \"ADMIN\" } }"}) {
	id: ID! 
	prize: Float! 
}

I am running in Flexible mode.

I don’t get this, you listed the same fields User.prize and User.prize.
While we talking about this, why do I see this?

txn {
  start_ts: 320009
  commit_ts: 320010
  preds: "1-prize"
}

Why is a 1- put in front? My guess is this is related to the problems I am having.

I have two applications I need to build, I have the clients who will be accessing via GraphQL exclusively, mostly subscriptions and then the backend application which will need to use DQL as it needs to commit multiple transactions as one.

Well, I am not entirely sure the meaning behind the 1- but that has nothing to do with your problem at hand.

With this your GraphQL Schema

I am able to open up Ratel and run the following DQL:

{
  set {
    _:g1 <dgraph.type> "Game" .
    _:g1 <Game.prize> "100.00" .
    _:g2 <dgraph.type> "Game" .
    _:g2 <Game.prize> "200.00" .
  }
}

Which is adding two games. And I will get a response similiar to:

{
  "data": {
    "code": "Success",
    "message": "Done",
    "queries": null,
    "uids": {
      "g1": "0x30d96",
      "g2": "0x30d97"
    }
  },
  "extensions": {
    "server_latency": {
      "parsing_ns": 13349,
      "processing_ns": 1584383,
      "assign_timestamp_ns": 638580,
      "total_ns": 2311599
    },
    "txn": {
      "start_ts": 480657,
      "commit_ts": 480658,
      "preds": [
        "1-Game.prize",
        "1-dgraph.type"
      ]
    }
  }
}

From the example in the previous posts above, with the predicates User.prize and User.name you should not be getting the response 1-prize, but rather 1-User.prize if done correctly.