tessl install tessl/golang-cloud-google-com--go--spanner@1.87.2Official 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,
}