Official Google Cloud Spanner client library for Go providing comprehensive database operations, transactions, and admin functionality
—
Guide to working with primary keys, key ranges, and key sets for read and delete operations.
type Key []interface{}A Key represents a row's primary key or secondary index key.
Creation:
// Single column key
key := spanner.Key{"alice"}
// Composite key
key := spanner.Key{"alice", 123}
// With typed values
key := spanner.Key{int64(1), "alice", time.Now()}Supported Types:
int, int8, int16, int32, int64, NullInt64 → INT64
uint8, uint16, uint32 → INT64
float32, float64, NullFloat64 → FLOAT64
bool, NullBool → BOOL
[]byte → BYTES
string, NullString → STRING
time.Time, NullTime → TIMESTAMP
civil.Date, NullDate → DATE
protoreflect.Enum, NullProtoEnum → ENUMfunc (k Key) AsPrefix() KeyRange
func (k Key) String() stringAsPrefix Example:
// Get all rows where key starts with "alice"
key := spanner.Key{"alice"}
keyRange := key.AsPrefix()
iter := client.Single().Read(ctx, "Users", keyRange, columns)type KeyRange struct {
Start, End Key
Kind KeyRangeKind
}
type KeyRangeKind int
const (
ClosedOpen KeyRangeKind = iota // [Start, End)
ClosedClosed // [Start, End]
OpenClosed // (Start, End]
OpenOpen // (Start, End)
)func (kr KeyRange) String() stringExamples:
// [1, 100) - includes 1, excludes 100
kr := spanner.KeyRange{
Start: spanner.Key{1},
End: spanner.Key{100},
Kind: spanner.ClosedOpen, // Default
}
// [1, 100] - includes both
kr := spanner.KeyRange{
Start: spanner.Key{1},
End: spanner.Key{100},
Kind: spanner.ClosedClosed,
}
// Composite key range
kr := spanner.KeyRange{
Start: spanner.Key{"alice", "2023-01-01"},
End: spanner.Key{"alice", "2023-12-31"},
Kind: spanner.ClosedClosed,
}
// Prefix range (all keys starting with "alice")
kr := spanner.Key{"alice"}.AsPrefix()type KeySet interface {
// Has unexported methods
}
func AllKeys() KeySet
func KeySets(keySets ...KeySet) KeySet
func KeySetFromKeys(keys ...Key) KeySetAllKeys:
// Read all rows
iter := client.Single().Read(ctx, "Users", spanner.AllKeys(), columns)KeySets - Union of Keys and Ranges:
// Combine multiple keys and ranges
ks := spanner.KeySets(
spanner.Key{1},
spanner.Key{5},
spanner.KeyRange{Start: spanner.Key{10}, End: spanner.Key{20}},
)
iter := client.Single().Read(ctx, "Users", ks, columns)KeySetFromKeys:
keys := []spanner.Key{
spanner.Key{1},
spanner.Key{2},
spanner.Key{3},
}
ks := spanner.KeySetFromKeys(keys...)
iter := client.Single().Read(ctx, "Users", ks, columns)key := spanner.Key{"alice"}
row, err := client.Single().ReadRow(ctx, "Users", key, []string{"name", "email"})keys := spanner.KeySets(
spanner.Key{"alice"},
spanner.Key{"bob"},
spanner.Key{"charlie"},
)
iter := client.Single().Read(ctx, "Users", keys, []string{"name", "email"})// Users with IDs from 1 to 100
kr := spanner.KeyRange{
Start: spanner.Key{1},
End: spanner.Key{100},
}
iter := client.Single().Read(ctx, "Users", kr, []string{"name", "email"})m := spanner.Delete("Users", spanner.Key{"alice"})
_, err := client.Apply(ctx, []*spanner.Mutation{m})// Delete users 1-99
kr := spanner.KeyRange{
Start: spanner.Key{1},
End: spanner.Key{100},
Kind: spanner.ClosedOpen,
}
m := spanner.Delete("Users", kr)
_, err := client.Apply(ctx, []*spanner.Mutation{m})m := spanner.Delete("Users", spanner.AllKeys())
_, err := client.Apply(ctx, []*spanner.Mutation{m})// Table: UserEvents (UserName STRING, EventDate STRING)
// Primary key: (UserName, EventDate)
// Read single event
key := spanner.Key{"Bob", "2023-09-23"}
row, err := client.Single().ReadRow(ctx, "UserEvents", key, columns)
// Read all events for Bob in 2023
kr := spanner.KeyRange{
Start: spanner.Key{"Bob", "2023-01-01"},
End: spanner.Key{"Bob", "2024-01-01"},
Kind: spanner.ClosedOpen,
}
iter := client.Single().Read(ctx, "UserEvents", kr, columns)// All events for Bob (any date)
key := spanner.Key{"Bob"}
kr := key.AsPrefix() // Matches all keys starting with "Bob"
iter := client.Single().Read(ctx, "UserEvents", kr, columns)For tables with descending keys:
// Table with DESC key: CREATE TABLE T (Key INT64) PRIMARY KEY(Key DESC)
// Range from 100 down to 1 (inclusive)
kr := spanner.KeyRange{
Start: spanner.Key{100}, // Larger value first
End: spanner.Key{1}, // Smaller value second
Kind: spanner.ClosedClosed,
}Install with Tessl CLI
npx tessl i tessl/golang-cloud-google-com--go--spanner