Creating, Retrieving, Updating, and Deleting Entities

Data objects in Datastore are known as entities, each of which is categorized under a particular kind for the purpose of queries. For instance, if you are writing a human resources application you might represent each employee with an entity of kind Employee. Note that the entity data values are in the form of properties. For more information about entities, see the concept document Entities, Properties, and Keys.

Creating entities and setting properties

In Go, you create a new entity by constructing an instance of a Go struct, populating its fields, and calling datastore.Put to save it to Datastore. Only exported fields (beginning with an upper case letter) will be saved to Datastore. You can specify the entity's key name by passing a non-empty stringID argument to datastore.NewKey.

The following example creates an entity of kind Employee, populates its property values, and saves it to Datastore:

import (
	"context"
	"time"

	"google.golang.org/appengine/datastore"
)

type Employee struct {
	FirstName          string
	LastName           string
	HireDate           time.Time
	AttendedHRTraining bool
}

func f(ctx context.Context) {
	// ...
	employee := &Employee{
		FirstName: "Antonio",
		LastName:  "Salieri",
		HireDate:  time.Now(),
	}
	employee.AttendedHRTraining = true

	key := datastore.NewIncompleteKey(ctx, "Employee", nil)
	if _, err := datastore.Put(ctx, key, employee); err != nil {
		// Handle err
	}
	// ...
}

The Employee type declares four fields for the data model: FirstName, LastName, HireDate, and AttendedHRTraining.

If you provide a empty key name, or use datastore.NewIncompleteKey, Datastore will automatically generate a numeric ID for the entity's key:

employee := &Employee{
	FirstName: "Antonio",
	LastName:  "Salieri",
	HireDate:  time.Now(),
}
employee.AttendedHRTraining = true
key := datastore.NewIncompleteKey(ctx, "Employee", nil)
_, err = datastore.Put(ctx, key, employee)

Retrieving entities

To retrieve an entity identified by a given key, pass the *datastore.Key as an argument to the datastore.Get function. You can generate the *datastore.Key using the datastore.NewKey function.

employeeKey := datastore.NewKey(ctx, "Employee", "asalieri", 0, nil)
addressKey := datastore.NewKey(ctx, "Address", "", 1, employeeKey)
var addr Address
err = datastore.Get(ctx, addressKey, &addr)

datastore.Get populates an instance of the appropriate Go struct.

Updating entities

To update an existing entity, modify the attributes of the struct, then call datastore.Put. The data overwrites the existing entity. The entire object is sent to Datastore with every call to datastore.Put.

Deleting entities

Given an entity's key, you can delete the entity with the datastore.Delete function:

key := datastore.NewKey(ctx, "Employee", "asalieri", 0, nil)
err = datastore.Delete(ctx, key)

Deleting entities in bulk

If you need to delete a large number of entities, we recommend using Dataflow to delete entities in bulk.

Using batch operations

You can use the following batch operations if you want to operate on multiple entities in a single Datastore call:

Here is an example of a batch call:

// A batch put.
_, err = datastore.PutMulti(ctx, []*datastore.Key{k1, k2, k3}, []interface{}{e1, e2, e3})

// A batch get.
var entities = make([]*T, 3)
err = datastore.GetMulti(ctx, []*datastore.Key{k1, k2, k3}, entities)

// A batch delete.
err = datastore.DeleteMulti(ctx, []*datastore.Key{k1, k2, k3})

Batch operations do not change your costs. You will be charged for every key in a batched operation, whether or not each key exists. The size of the entities involved in an operation does not affect the cost.