F-strings vs variables

Hi,

I am using the python SDK.
when creating queries or mutations I can use f-string to alter the query on runtime.
is it ok or should I use variables?

Thaks,
Or

Hi @spinelsun

DQL upserts don’t support variables yet, so IMO F-strings (string interpolation) is a good option here.
For queries, using variables is better programming practice as it allows independent testing of query artifacts.

Hi @anand

The txn.do_request function allows you to run upserts consisting of one query and one mutation. Query variables could be defined and can then be used in the mutation.
To know more about upsert, we highly recommend going through the mutations docs.

It says one query and one mutation but in the upsert documentation, it said that an upsert can have several mutations. The SDK gets an array of Mutation in txn.create_request function.
Also, the SDK allows to pass variables in txn.create_request so will it work or fail if using this option instead of f-string?

  1. We can send multiple mutation in the upsert block.
  2. I could not find an example using a request with variables.
    @MichelDiz Could you please advise?

Not sure, @martinmr might help.

One thing to mention is that DQL Vars (A.K.A. old “GraphQL Variables”) can be used in dgo client. I remember that some user was using this. Not sure if you guys are talking about same variable tho.

@anand:

  1. Ok, so it will be grate if you update the readme file in pydgraph github page.

@MichelDiz @martinmr, this is the code that I used to implement an upsert with condition:

    with db_utils.get_client() as client:
        query = """
        {
            KEY as var(func: uid($uid))
        }
        """
        condition = "@if(eq(len(key), 1))"
        variables = {'$uid': uid}
        data = f"uid(KEY) <ApiKeySet.title> {new_title}"
        txn = client.txn()
        try:
            mutation = txn.create_mutation(cond=condition, set_nquads=data)
            db_request = txn.create_request(mutations=[mutation],
                                            query=query,
                                            variables=variables,
                                            commit_now=True)
            result = txn.do_request(db_request)
        except pydgraph.AbortedError as pdae:
            msg = f'Operation failed due to the following error: {str(pdae)}'

            return Response(msg, status.HTTP_500_INTERNAL_SERVER_ERROR)

    response = json.loads(result.json)
    succeeded = response['code'].lower() == 'success'
    response_msg = response['message']

    if not succeeded:
        return Response(response_msg, status.HTTP_500_INTERNAL_SERVER_ERROR)

    return Response(_SUCCESS_MESSAGE, status.HTTP_200_OK)

I used DQL Vars and query Vars, which according to the documentation, both should work.
If you something that is not correct please let me know

Also for some reasone the upsert with condition doesn’t work in Ratel do you know why?
This is what I do:

upsert{
  query {
    U as q(func: uid("0x222ef")){
       uid
    }
  }

  mutation @if(eq(len(U), 1)) {
    set {
        uid(U) <ApiKeySet.access_key> "eoxsp1XJoVCKBSwmoasj" .
    }
  }
}

The condition is always skipped and the set works no matter which uid I give even if it doesn’t exist in the db

Ratel uses dgraph-js-http. The HTTP API badly supports the DQL Vars. That’s something we need to take a look at. One of the points is that the mutation operation was never meant to accept DQL Vars. Just the Query operation. In Ratel you just use a single operation per query(in a gRPC client you can run several operations), which in this case is Mutation.

Hi @spinelsun
I have accepted this and marked this for documentation changes. Thanks for the feedback.

@MichelDiz Ok so for now you say that Ratel can’t handle the upsert operation?
If that’s what you mean I would be happy to know when you fix it.

Thanks alot

It can, what it can’t is using DQL Vars in Upsert queries.

By saying DQL vars you mean the variable like GQL?
I didn’t use them in my upsert, I used only query variables which is the only way I can pass the uid of the quiried node.
The upsert I mentioned above doesn’t work - it ignores the condition and always set the triple even if the query returns nothing

No, I’m talking about this https://dgraph.io/docs/query-language/graphql-variables/

So, as you don’t know what it was. Just ignore what I have said.

You should not rely on your conditions in the UID U as q(func: uid("0x222ef")){ cuz the UID will always be true in Dgraph. Change it to a value that you know that the entity should have. Or use @cascade directive and add some fields.

1 Like

Hi, @spinelsun! That section of the readme file for pydgraph is now updated in the following PR: https://github.com/dgraph-io/pydgraph/pull/161

Thanks for raising this issue.