# Cannot set value in \[uid\] predicate in golang: "Input for predicate "predicate\_name" of type uid is scalar"

**URL:** <https://discuss.dgraph.io/t/cannot-set-value-in-uid-predicate-in-golang-input-for-predicate-predicate-name-of-type-uid-is-scalar/14436>\
**Category:** Dgraph\
**Tags:** dgraph\
**Created:** [June 4, 2021, 1:19pm UTC](https://discuss.dgraph.io/t/cannot-set-value-in-uid-predicate-in-golang-input-for-predicate-predicate-name-of-type-uid-is-scalar/14436 "2021-06-04T13:19:10Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![vpoletaev11](https://yyz1.discourse-cdn.com/flex007/user_avatar/discuss.dgraph.io/vpoletaev11/32/8353_2.png) [@vpoletaev11](https://discuss.dgraph.io/u/vpoletaev11)\
**Post date:** [June 4, 2021, 1:19pm UTC](https://discuss.dgraph.io/t/cannot-set-value-in-uid-predicate-in-golang-input-for-predicate-predicate-name-of-type-uid-is-scalar/14436/1 "2021-06-04T13:19:10Z")

</div>

Hello everyone!  
I have some trouble in connecting two nodes.

## What I want to do

I try to make two nodes Device and Rule with connection o2m.  
There is the code:

```auto
package main

import (
	"context"
	"encoding/json"
	"fmt"
	"log"

	"github.com/dgraph-io/dgo/v210"
	"github.com/dgraph-io/dgo/v210/protos/api"
	"google.golang.org/grpc"
)

const schema = `rule.name: string @index(exact) .
device.name: string @index(exact) .
device.rules: [uid] .
`

type Rule struct {
	Uid int `json:"uid,omitempty"`
	Name string `json:"rule.name,omitempty"`
}
type Device struct {
	Uid int `json:"uid,omitempty"`
	Name string `json:"device.name,omitempty"`
	Rules []int `json:"device.rules,omitempty"`
}

var ctx = context.TODO()

func main() {
	// Set db connection
	conn, err := grpc.Dial("localhost:9080", grpc.WithInsecure())
	if err != nil {
		log.Fatal(err)
	}
	defer conn.Close()
	dgraphClient := dgo.NewDgraphClient(api.NewDgraphClient(conn))

	op := &api.Operation{
		Schema: schema,
	}
	err = dgraphClient.Alter(ctx, op)
	if err != nil {
		panic(err)
	}

	// Create rule
	txn := dgraphClient.NewTxn()
	defer txn.Discard(ctx)

	r := Rule{
		Uid: 1,
		Name: "Rule1",
	}

	pb, err := json.Marshal(r)
	if err != nil {
		log.Fatal(err)
	}

	mu := &api.Mutation{
		SetJson: pb,
		CommitNow: true,
	}
	res, err := txn.Mutate(ctx, mu)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(res)

	// Create Device
	txn = dgraphClient.NewTxn()
	defer txn.Discard(ctx)

	d := Device{
		Uid: 2,
		Name: "Device1",
		Rules: []int{1},
	}

	pb, err = json.Marshal(d)
	if err != nil {
		log.Fatal(err)
	}

	mu = &api.Mutation{
		SetJson: pb,
		CommitNow: true,
	}
	res, err = txn.Mutate(ctx, mu)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(res)
}

```

The trouble begins when I try to set Device.Rules. There its text:

```auto
2021/06/04 15:24:26 rpc error: code = Unknown desc = Input for predicate "device.rules" of type uid is scalar. Edge: entity:2 attr:"\000\000\000\000\000\000\000\000device.rules" value:"\001\000\000\000\000\000\000\000" value_type:INT 
exit status 1

```

So how can I set Device.Rules uids?

## What I did

This works absolutely fine when I do it in Ratel.

## Dgraph metadata

> **dgraph version**
>
> v21.03.0

---

<div class="post-metadata">

**Author:** ![iluminae](https://yyz1.discourse-cdn.com/flex007/user_avatar/discuss.dgraph.io/iluminae/32/7367_2.png) [@iluminae](https://discuss.dgraph.io/u/iluminae)\
**Post date:** [June 4, 2021, 1:33pm UTC](https://discuss.dgraph.io/t/cannot-set-value-in-uid-predicate-in-golang-input-for-predicate-predicate-name-of-type-uid-is-scalar/14436/2 "2021-06-04T13:33:11Z")

</div>

Hi - see the https://dgraph.io/docs/mutations/json-mutation-format/#edges-between-nodes on using the json mutation format to create edges.

TL;DR: you make a nested struct, not an integer field.

---

<div class="post-metadata">

**Author:** ![vpoletaev11](https://yyz1.discourse-cdn.com/flex007/user_avatar/discuss.dgraph.io/vpoletaev11/32/8353_2.png) [@vpoletaev11](https://discuss.dgraph.io/u/vpoletaev11)\
**Post date:** [June 4, 2021, 2:11pm UTC](https://discuss.dgraph.io/t/cannot-set-value-in-uid-predicate-in-golang-input-for-predicate-predicate-name-of-type-uid-is-scalar/14436/3 "2021-06-04T14:11:09Z")

</div>

Thank you for your reply.  
It is strange to me after using relational databases. Looks like this storing data are natural way for dgraph. But what if I want to add nodes without relations, but add them later. How should I link them later in that case? I mean add in database two (for example) separate nodes and after some time join them. I want to avoid data replication. (Will adding relations between for example rule and device create copy of rule for device?)  
Also one node can have many relations with other nodes. So every node should store copy of it? I mean if we create nodes with same nested node for example many devices with one rule, is every device will store copy of rule ? Or dgraph under the hood use pointer on that node instead it copy ?

---

<div class="post-metadata">

**Author:** ![iluminae](https://yyz1.discourse-cdn.com/flex007/user_avatar/discuss.dgraph.io/iluminae/32/7367_2.png) [@iluminae](https://discuss.dgraph.io/u/iluminae)\
**Post date:** [June 4, 2021, 2:17pm UTC](https://discuss.dgraph.io/t/cannot-set-value-in-uid-predicate-in-golang-input-for-predicate-predicate-name-of-type-uid-is-scalar/14436/4 "2021-06-04T14:17:09Z")

</div>

I would highly suggest using the protobuf NQuads interface within the go library to use a typed system of inserting data, as opposed to the `SetJson` member of the requests. (its basically a protobuf representation of the RDF format, if you prefer string building, you can use that).

With the NQuads typed interface, you can just set the `ObjectId ` to the uid(eg: 0x123) you wish to point to within a NQuad object.

You can also use [upserts](https://dgraph.io/docs/mutations/upsert-block) to look up ids as well, if you had not read up on that as well.

---

<div class="post-metadata">

**Author:** ![vpoletaev11](https://yyz1.discourse-cdn.com/flex007/user_avatar/discuss.dgraph.io/vpoletaev11/32/8353_2.png) [@vpoletaev11](https://discuss.dgraph.io/u/vpoletaev11)\
**Post date:** [June 4, 2021, 3:11pm UTC](https://discuss.dgraph.io/t/cannot-set-value-in-uid-predicate-in-golang-input-for-predicate-predicate-name-of-type-uid-is-scalar/14436/5 "2021-06-04T15:11:34Z")

</div>

I finally did it.  
I can refer to [dgo/example\_set\_object\_test.go at master · dgraph-io/dgo · GitHub](https://github.com/dgraph-io/dgo/blob/master/example_set_object_test.go).  
There every one who wonder can see how to link nodes.

There is my working prototype. Is that Go way to do this?

```auto
package main

import (
	"context"
	"encoding/json"
	"fmt"
	"log"

	"github.com/dgraph-io/dgo/v210"
	"github.com/dgraph-io/dgo/v210/protos/api"
	"google.golang.org/grpc"
)

const schema = `rule.name: string @index(exact) .
device.name: string @index(exact) .
device.rules: [uid] .
`

type Rule struct {
	Uid int `json:"uid,omitempty"`
	Name string `json:"rule.name,omitempty"`
}
type Device struct {
	Uid int `json:"uid,omitempty"`
	Name string `json:"device.name,omitempty"`
	Rules []Rule `json:"device.rules,omitempty"`
}

var ctx = context.TODO()

func main() {
	// Set db connection
	conn, err := grpc.Dial("localhost:9080", grpc.WithInsecure())
	if err != nil {
		log.Fatal(err)
	}
	defer conn.Close()
	dgraphClient := dgo.NewDgraphClient(api.NewDgraphClient(conn))

	op := &api.Operation{
		Schema: schema,
	}
	err = dgraphClient.Alter(ctx, op)
	if err != nil {
		panic(err)
	}

	// Create rule
	txn := dgraphClient.NewTxn()
	defer txn.Discard(ctx)

	r := Rule{
		Uid: 1,
		Name: "Rule1",
	}

	pb, err := json.Marshal(r)
	if err != nil {
		log.Fatal(err)
	}

	mu := &api.Mutation{
		SetJson: pb,
		CommitNow: true,
	}
	res, err := txn.Mutate(ctx, mu)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(res)

	// Create Device
	txn = dgraphClient.NewTxn()
	defer txn.Discard(ctx)

	d := Device{
		Uid: 2,
		Name: "Device1",
		Rules: []Rule{{Uid: 1}},
	}

	pb, err = json.Marshal(d)
	if err != nil {
		log.Fatal(err)
	}

	mu = &api.Mutation{
		SetJson: pb,
		CommitNow: true,
	}
	res, err = txn.Mutate(ctx, mu)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(res)
}

```

As I understood it will not fully copy rule in the device but just write it uid in device.rules.

---

<div class="post-metadata">

**Author:** ![iluminae](https://yyz1.discourse-cdn.com/flex007/user_avatar/discuss.dgraph.io/iluminae/32/7367_2.png) [@iluminae](https://discuss.dgraph.io/u/iluminae)\
**Post date:** [June 4, 2021, 3:14pm UTC](https://discuss.dgraph.io/t/cannot-set-value-in-uid-predicate-in-golang-input-for-predicate-predicate-name-of-type-uid-is-scalar/14436/6 "2021-06-04T15:14:47Z")

</div>

Yea if it works for you, go at it. Especially if you (somehow) know the UIDs you are connecting. Often users would have to look up a UID since they are not-so user controllable (eg: if you put in a big UID it will fail if the zero has not leased it out yet). I do not think(?) the json interface will allow you to upsert. (caveat: I do not use the json mutation method and may be wrong there)

---

<div class="post-metadata">

**Author:** ![vpoletaev11](https://yyz1.discourse-cdn.com/flex007/user_avatar/discuss.dgraph.io/vpoletaev11/32/8353_2.png) [@vpoletaev11](https://discuss.dgraph.io/u/vpoletaev11)\
**Post date:** [June 4, 2021, 3:17pm UTC](https://discuss.dgraph.io/t/cannot-set-value-in-uid-predicate-in-golang-input-for-predicate-predicate-name-of-type-uid-is-scalar/14436/7 "2021-06-04T15:17:11Z")

</div>

Thank You.
