• Start

Languages

/

Go

/

Concepts

Data manipulation

The Go SDK provides generic functions for selecting, creating, updating, and deleting records in SurrealDB.

The Go SDK provides generic top-level functions for common CRUD operations on records and tables. These functions work with *DB, *Session, and *Transaction through the sendable constraint, and return typed results through Go generics.

This page covers how to target tables and records, and how to select, create, insert, update, merge, patch, and delete data.

Function

Description

surrealdb.Select[T](ctx, s, what)

Selects all records from a table, or a specific record

surrealdb.Create[T](ctx, s, what, data)

Creates a new record with optional data

surrealdb.Insert[T](ctx, s, table, data)

Inserts one or multiple records into a table

surrealdb.InsertRelation[T](ctx, s, rel)

Inserts a relation record between two records

surrealdb.Relate[T](ctx, s, rel)

Creates a relation with an auto-generated ID

surrealdb.Update[T](ctx, s, what, data)

Replaces the entire content of a record or all records in a table

surrealdb.Upsert[T](ctx, s, what, data)

Creates a record if it does not exist, or replaces it entirely

surrealdb.Merge[T](ctx, s, what, data)

Merges data into a record, preserving unmentioned fields

surrealdb.Patch(ctx, s, what, patches)

Applies JSON Patch operations to a record or table

surrealdb.Delete[T](ctx, s, what)

Deletes a specific record or all records from a table

Most data manipulation functions accept a what parameter that determines the scope of the operation. You can pass a Table to target all records in a table, or a RecordID to target a specific record.

import "github.com/surrealdb/surrealdb.go/pkg/models"

all, err := surrealdb.Select[[]Person](ctx, db, models.Table("persons"))

one, err := surrealdb.Select[Person](ctx, db, models.NewRecordID("persons", "tobie"))

When a Table is passed, operations that return data return a slice. When a RecordID is passed, they return a single value. Use the appropriate type parameter to match.

Select retrieves records from the database. Pass a Table to get all records, or a RecordID to get a single record.

persons, err := surrealdb.Select[[]Person](ctx, db, models.Table("persons"))
if err != nil {
	log.Fatal(err)
}

tobie, err := surrealdb.Select[Person](ctx, db, models.NewRecordID("persons", "tobie"))
if err != nil {
	log.Fatal(err)
}

Create creates a new record. Pass a Table to generate a random ID, or a RecordID to specify the ID explicitly. The data can be a struct or a map.

person, err := surrealdb.Create[Person](ctx, db, models.Table("persons"), Person{
	Name:    "Tobie",
	Surname: "Morgan Hitchcock",
})

specific, err := surrealdb.Create[Person](ctx, db, models.NewRecordID("persons", "tobie"), map[string]any{
	"name":    "Tobie",
	"surname": "Morgan Hitchcock",
})

Insert inserts one or more records into a table. This is useful for bulk operations.

persons, err := surrealdb.Insert[Person](ctx, db, models.Table("persons"), []map[string]any{
	{"name": "Alice", "age": 30},
	{"name": "Bob", "age": 25},
})

The SDK provides two ways to create graph edges between records.

Relate creates a relation with an auto-generated ID. The Relationship.ID field is ignored.

rel, err := surrealdb.Relate[map[string]any](ctx, db, &surrealdb.Relationship{
	In:       models.NewRecordID("persons", "tobie"),
	Out:      models.NewRecordID("posts", "first"),
	Relation: models.Table("wrote"),
	Data:     map[string]any{"created_at": "2026-01-01T00:00:00Z"},
})

InsertRelation works like Insert but for relation tables. It allows you to specify the ID explicitly via the Relationship.ID field.

rel, err := surrealdb.InsertRelation[map[string]any](ctx, db, &surrealdb.Relationship{
	In:       models.NewRecordID("persons", "tobie"),
	Out:      models.NewRecordID("posts", "first"),
	Relation: models.Table("wrote"),
})

Update replaces the entire content of a record or all records in a table. Fields not included in the new data are removed.

updated, err := surrealdb.Update[Person](ctx, db, models.NewRecordID("persons", "tobie"), Person{
	Name:    "Tobie",
	Surname: "Morgan Hitchcock",
})
Note

Because Update performs a full replacement, omitted fields are deleted from the record. Use Merge if you want to preserve existing fields.

Upsert creates a record if it does not already exist, or replaces it entirely if it does.

person, err := surrealdb.Upsert[Person](ctx, db, models.NewRecordID("persons", "tobie"), Person{
	Name:    "Tobie",
	Surname: "Morgan Hitchcock",
})

Merge deep-merges the provided data into the existing record, preserving fields not mentioned in the merge payload.

merged, err := surrealdb.Merge[Person](ctx, db, models.NewRecordID("persons", "tobie"), map[string]any{
	"age": 35,
})

Patch applies JSON Patch (RFC 6902) operations to a record or all records in a table. Each operation is a PatchData with Op, Path, and Value fields.

patches, err := surrealdb.Patch(ctx, db, models.NewRecordID("persons", "tobie"), []surrealdb.PatchData{
	{Op: "replace", Path: "/surname", Value: "Hitchcock"},
	{Op: "add", Path: "/verified", Value: true},
})

Supported operations include add, remove, replace, move, copy, and test.

Delete removes a specific record or all records from a table. The function returns the deleted record(s).

deleted, err := surrealdb.Delete[Person](ctx, db, models.NewRecordID("persons", "tobie"))

allDeleted, err := surrealdb.Delete[[]Person](ctx, db, models.Table("persons"))

Was this page helpful?