Entity values coming to Cloud Datastore client

1,034 views
Skip to first unread message

Sarah Adams

unread,
Nov 1, 2016, 4:54:38 PM11/1/16
to google-api-go-announce

The cloud.google.com/go/datastore package will soon support entity values. This change affects how nested structs are stored in Datastore, but should not change the semantics of your application.


What are Entity Values?


Historically, a nested struct like this:

type Human struct {

 Name string

 Pet  Animal

}


type Animal struct {

 Type string

}


me := Human{

 Name: "Susan",

 Pet:  Animal{Type: "dog"},

}

would have been serialized and stored by the "cloud.google.com/go/datastore" package in Datastore as a flattened set of its nested fields. In this example, the package would serialize two string fields, one with name Pet.Type and value "dog", and one with name Name and value "Susan".


With support for Entity values, this nested struct will now be serialized and stored in Datastore as two fields, one with name Name and value "Susan", and one with name Pet and Entity value “{"Type": "dog"}”.


An Entity value can also have an associated Datastore key. To add a key to your Entity value, add a field to your entity value type (in this case, Animal) of type *datastore.Key and tag it with `datastore:"__key__"`:

type Human struct {

 Name string

 Pet  Animal

}


type Animal struct {

 Type string

 K *datastore.Key `datastore:"__key__"`

}


Use in conjunction with appengine packages

If you use the "cloud.google.com/go/datastore" ("cloud") package in conjunction with the "google.golang.org/appengine/datastore" or "appengine/datastore" ("appengine") packages, you should not store an Entity value Key in your embedded struct (tagged as `datastore:"__key__"`). The appengine datastore packages have no concept of Entity  values nor their embedded Keys. If you read an Entity value with an embedded  Key from an App Engine application, the Key will be dropped.


The appengine packages will continue to fail to load a slice of structs with an embedded slice field like:


type State struct {

 Cities  []struct{

   Populations []int

 }

}


An error will be returned when you try to retrieve it from Datastore. Your data in Datastore will not be affected.

If you use the cloud package in conjunction with the appengine packages, do not use this new feature.


If you have any concerns about this new pattern of encoding and storing nested structs as Entity values instead of a flattened set of attributes, you may want to opt out until you can test and redeploy your application. To opt out, tag each nested struct field with the tag ",flatten".

type Human struct {

 Name string

 Pet  Animal `datastore:",flatten"`

}


type Animal struct {

 Type string

}


The "appengine/datastore", "google.golang.org/appengine/datastore" and "cloud.google.com/go/datastore" packages can each load entity values and flattened sets of attributes into nested Go structs. However, the cloud datastore package will default to writing your nested structs as entity values, while the appengine datastore packages will only write your nested structs as flattened sets of attributes.


If you write nested structs lacking the ",flatten" tag with both the cloud and appengine packages, the stored representation will be written as either flattened sets of attributes or Entity values, depending on which package is used. Except the issues with Keys and slices of structs mentioned above, this should not affect the behavior of your application.


Jonathan Amsterdam

unread,
Nov 8, 2016, 4:14:39 PM11/8/16
to google-api-go-announce
These changes are in.
Reply all
Reply to author
Forward
0 new messages