Upsert not working golang

(Barum) #1

I am trying to use upsert but having issues. this is an example of my go code:

import (


// If omitempty is not set, then edges with empty values (0 for int/float, "" for string, false
// for bool) would be created for values not specified explicitly.

type App struct {
	Uid     string `json:"uid,omitempty"`
	AppID   string `json:"apps.apps.app_id, omitempty"`
	AppDesc string `json:"apps.apps.app_desc, omitempty"`

func main() {
	conn, err := grpc.Dial("", grpc.WithInsecure())
	if err != nil {
		log.Fatal("While trying to dial gRPC")
	defer conn.Close()

	dc := api.NewDgraphClient(conn)
	dg := dgo.NewDgraphClient(dc)

	//dob := time.Date(1980, 01, 01, 23, 0, 0, 0, time.UTC)
	// While setting an object if a struct has a Uid then its properties in the graph are updated
	// else a new node is created.
	// In the example below new nodes for Alice, Bob and Charlie and school are created (since they
	// dont have a Uid).
	p := App{
		AppID:   "APPID01",
		AppDesc: "this is app01",

	op := &api.Operation{}
	op.Schema = `
		apps.apps.app_id: string @index(exact) @upsert .
		apps.apps.app_desc: string .


	ctx := context.Background()
	err = dg.Alter(ctx, op)
	if err != nil {

	mu := &api.Mutation{
		CommitNow: true,
	pb, err := json.Marshal(p)
	if err != nil {

	mu.SetJson = pb
	_, err = dg.NewTxn().Mutate(ctx, mu)
	if err != nil {

	// Assigned uids for nodes which were created would be returned in the assigned.Uids map.
	//variables := map[string]string{"$id": assigned.Uids["blank-0"]}
	q := `
			lookup(func: eq(apps.apps.app_id, "APPID01")){

	resp, err := dg.NewTxn().Query(ctx, q)
	if err != nil {

	type Root struct {
		Me []App `json:"me"`

	var r Root
	err = json.Unmarshal(resp.Json, &r)
	if err != nil {
	// fmt.Printf("Me: %+v\n", r.Me)
	// R.Me would be same as the person that we set above.


what am I missing?

(Michel Conrado) #2

Check this test file

You need to query and then mutate, using the upsert procedure.

(Barum) #3

Thank you for the example.
Question: I thought the @upsert was supposed to take care of duplicate inserts?
Whats the point of having the @upsert if I have to do a READ before WRITE?

(Michel Conrado) #4

Yeah, actually the upsert directive takes care of duplicate during transactions. It’s not a kind of “lock” ou automation. But we are working in a better upsert feature here


So, Dgraph has “Upsert directive” and “Upsert procedure”. They’re different but for the same purpose, you need to use both together. Upsert procedure is basically a transaction with a query and then a mutation.

I think #3059 will cover this need better soon.