Store err with geo and map[string]interface{}

Moved from GitHub dgo/72

Posted by drwpeng:

There is a map[string]interface{} in structs. If I add “data: geo .” to schema:

  • if there is no data in the dgraph:
    This will not be able to save data and no error message
  • if there is data in the dgraph:
    rpc error: code = unknown desc = Schema change not allowed from scalar to uid or vice versa while there is data for pred: data

My test case as follows:

package main

import (

type Animal struct {
	Id   string `json:"id,omitempty"`
	Name string `json:"name,omitempty"`
	Info string `json:"info,omitempty"`
	Size string `json:"size,omitempty"`

type PResult struct {
	ID       string                 `json:"id"`
	Name     string                 `json:"name,omitempty"`
	Category string                 `json:"category,omitempty"`
	Data     map[string]interface{} `json:"data,omitempty"`

func main() {
	conn, _ := grpc.Dial("localhost:9080", grpc.WithInsecure())
	dg := dgo.NewDgraphClient(api.NewDgraphClient(conn))

	ani := Animal{
		Id:   "12345",
		Name: "Tom",
		Info: "dog",
		Size: "10kg",
	pr := PResult{
		ID:       "f11111",
		Name:     "animal",
		Category: "friend",
		Data:     structs.Map(ani),

	op := &api.Operation{}
	op.Schema = `
		id:		  string @index(exact) .
		name:	  string .
        category: string .
		data:	  geo	 .

	ctx := context.Background()
	if err := dg.Alter(ctx, op); err != nil {
	mu := &api.Mutation{
		CommitNow: true,
	pb, _ := json.Marshal(pr)
	mu.SetJson = pb
	_, _ = dg.NewTxn().Mutate(ctx, mu)
	//	fmt.Println(assign.Uids["blank-0"])

campoy commented :

I’m not sure I follow the issue.
On the schema you set data to be of type geo, but then you’re passing a map[string]interface{}.

What’s the goal of this?

If you want to store a map[string]interface{} you are technically creating a new node with its own edges, so the schema should say that data is of type uid.

I just did this on Ratel and it worked.

<category>: string .
<data>: uid .
<id>: string @index(exact) .
<info>: default .
<name>: string .
<size>: default .

Your mutation would be akin to the following:

set {
  _:a <id> "f111111" .
  _:a <name> "animal" .
  _:a <category> "friend" .
  _:a <data> _:b .
  _:b <id> "12345" .
  _:b <name> "Tom" .
  _:b <info> "dog" .
  _:b <size> "10kg" .

And then a simple query like this will retrieve all the data.

  q(func: has(data)) {
    data {

If your schema already declares data as type uid and you send a query trying to alter the schema to geo you will get the error you mention:

I’ll close the issue, but feel free to reopen if you have any other questions or concerns.

drwpeng commented :

That’s all.
I don’t know there is a uid type, so I mistakenly used geo.
Thank you very much.