Mutate error in Go client when attempting to create new node with relationship

Hi,

I’m using the Go client and am having an issue when trying to add a new node with a relationship to an existing node.

Here’s an example of a schema and structs:

network: string .
address: string .
ip.network: uid @reverse .

type network struct {
    UID        string   `json:"uid,omitempty"`
    Network    string   `json:"network,omitempty"`
}

type ip struct {
    UID        string   `json:"uid,omitempty"`
    Address    string   `json:"address,omitempty"`
    NetworkUID string   `json:"ip.network,omitempty"`
}

I first create the network and store the result in a variable called nw.

I then want to create an IP address and add the relationship to the network by passing the network UID to the NetworkUID field of the ip struct.

So my, simplified, code then looks like this:

addr := ip{
    Address:  "192.168.1.1",
    NetworkUID:  nw.UID,
}

mu := &api.Mutation{
	CommitNow: true,
}
a, err := json.Marshal(addr)
if err != nil {
	fmt.Println(err)
}

mu.SetJson = a

_, err = dg.NewTxn().Mutate(context.Background(), mu)
if err != nil {
	fmt.Println(err)
}

And then I get the following error when attempting to run the mutation:

Transaction has been aborted. Please retry.

The JSON looks like this:

{
    "address":"192.168.1.1",
    "ip.network":"0xc451"
}

All works fine without trying to pass the relationship. I can add the relationship manually with no problems in Ratel, I’m just not sure how to do it via the Go client.

I must be doing something simple wrong…but I can’t work out what right now. Can anyone help?

Thanks :slight_smile:

Your general approach seems okay to me. It’s strange that you’re getting “transaction has been aborted” when just adding the ip.network, since there isn’t any indexing on that predicate which would cause aborts.

Are you running everything serially, or in parallel?

Is it possible to post code for the full example? That way I can try to reproduce the problem on my end.

Sure, I’ve put it on Github @ https://github.com/rokett/ip-test. I added a readme with the full schema and a quick explanation of how to add a new network.

Each IP is currently created sequentially automatically after the creation of the host network.

thanks for your help :slight_smile:

Cool, I’ll take a look at this today.

I took a look at your program and found what the problem is.

It has to do with how the JSON representing an ip object is structured. An example of the JSON your program generates is {"uid":0x01,"address":"192.168.0.1","ip.network":"0x02"}. It’s the ip.network that’s the problem here. For it to be an edge in the dgraph, it’s value should be a JSON object rather than a string. So what you really want is this: {"uid":0x01,"address":"192.168.0.1","ip.network":{"0x02"}}.

You could modify your Go structs as follows:

type network struct {
    UID        string   `json:"uid,omitempty"`
    Network    string   `json:"network,omitempty"`
}

type ip struct {
    UID        string   `json:"uid,omitempty"`
    Address    string   `json:"address,omitempty"`
    NetworkUID *network `json:"ip.network,omitempty"`
}

As for the “Transaction has been aborted, please retry” error message. It’s misleading and not too useful, since retrying (the same mutation) will not work. I’ll make a change for these sorts of error messages to be more useful.

FYI, there’s a fix in master (8e9bb37) for the error message. This will appear in the next release.

thanks Peter…that did the trick :slight_smile:

Appreciate the help, and I’m glad my issue helped to improve things in some small way.

1 Like

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.