Query, Live, Transactions

Auto-generated from docstrings. For narrative usage, see the Guide.

Query and CRUD

SurrealDB.queryFunction
query(client, sql::String; vars=Dict{String, Any}())

Execute a raw SurrealQL query with optional parameterized variables.

Returns Vector{Dict{String, Any}} — one result dict per statement.

Examples

result = SurrealDB.query(db, "SELECT * FROM stream WHERE active = true")
result = SurrealDB.query(db, "SELECT * FROM $table WHERE x > $min",
                         vars=Dict("table" => "stream", "min" => 10))
source
query(client, ::Type{T}, sql::String; vars=Dict{String, Any}())

Execute a raw SurrealQL query and map results to typed Julia structs.

T must be a type for which StructTypes.StructType(T) returns StructTypes.Struct(). Each result row is converted to an instance of T via StructTypes.constructfrom.

Returns Vector{T} — one instance per result row.

Examples

struct Stream
    id::SurrealDB.RecordID
    name::String
    mature::Bool
end
StructTypes.StructType(::Type{Stream}) = StructTypes.Struct()

streams = SurrealDB.query(db, Stream, "SELECT * FROM stream")
source
SurrealDB.query_verboseFunction
query_verbose(client, sql::String, vars=Dict{String,Any}()) -> Vector{QueryStatement}

Execute a SurrealQL query and return per-statement metadata, including status, execution time, result, and any typed error — one QueryStatement per server-reported statement in order.

Unlike query, query_verbose never throws on statement errors. Each statement's outcome is captured in the returned QueryStatement. Transport- level failures (network errors, ConnectionError, etc.) still propagate as exceptions.

Use cases:

  • Multi-statement transactions — inspect which statements succeeded or failed before deciding to retry.
  • Batch ETL with partial failure — continue processing successful statements while logging errors.
  • Per-statement performance profiling — read the time field from each QueryStatement to identify slow statements.
  • Observability pipelines — emit structured per-statement metrics without losing the result data.

Examples

# Partial failure: second INSERT has a duplicate id
stmts = SurrealDB.query_verbose(db, """
    INSERT INTO user { id: user:1, name: "Alice" };
    INSERT INTO user { id: user:1, name: "Duplicate" };
    SELECT * FROM user;
""")

# stmts[1] → QueryStatement(:ok, ..., rows=1)
# stmts[2] → QueryStatement(:err, ..., error=AlreadyExistsError(...))
# stmts[3] → QueryStatement(:ok, ..., rows=1)

successes = filter(isok, stmts)
failures  = filter(iserr, stmts)
times_ms  = [s.time for s in stmts]

For simple queries where you want the result or an exception, use query.

See also: QueryStatement, isok, iserr, query.

source
SurrealDB.QueryStatementType
QueryStatement

Per-statement metadata returned by query_verbose. Exposes the server-reported status, execution time, result value, and any typed error without discarding statements that errored.

Fields:

  • status::Symbol:ok or :err
  • time::String — server-reported execution time, e.g. "1.2ms"
  • result::Any — the parsed result value; nothing on :err
  • error::Union{ServerError, Nothing} — typed error; nothing on :ok

Use isok / iserr to discriminate:

stmts = SurrealDB.query_verbose(db, "SELECT * FROM a; BAD QUERY; SELECT * FROM b")
filter(isok, stmts)   # statements that succeeded
filter(iserr, stmts)  # statements that failed
source
SurrealDB.isokFunction
isok(s::QueryStatement) -> Bool

Return true when the statement completed without error.

source
SurrealDB.iserrFunction
iserr(s::QueryStatement) -> Bool

Return true when the statement produced a server error.

source
SurrealDB.query_tableFunction
query_table(client, sql::String; vars=Dict{String, Any}()) -> Vector{QueryResultTable}

Like query but returns one QueryResultTable per statement instead of nested vectors. Lets multi-statement queries preserve their per-statement structure as Tables.jl-compatible sources.

Embedded mode flattens statement boundaries

Remote (WS/HTTP) preserves per-statement results. Embedded (libsurreal) flattens all rows from all statements into a single result list (the C library does not expose statement boundaries). On embedded, query_table therefore returns a single-element Vector regardless of how many ;s the SQL contains. Run multi-statement queries one at a time on embedded if you need per-statement separation.

Examples

tables = SurrealDB.query_table(db, "SELECT * FROM stream; SELECT * FROM event")
using DataFrames
streams_df = DataFrame(tables[1])
events_df  = DataFrame(tables[2])

See also: query, query_one, to_table.

source
SurrealDB.query_oneFunction
query_one(client, sql::String; vars=Dict{String, Any}()) -> QueryResultTable

Convenience wrapper around query_table for single-statement queries. Asserts the SQL produced exactly one statement-result and returns its QueryResultTable. Throws ArgumentError if the query produced zero or multiple statements.

Examples

table = SurrealDB.query_one(db, "SELECT * FROM stream WHERE active = true")
using DataFrames
df = DataFrame(table)

See also: query, query_table.

source
SurrealDB.createFunction
create(client, what, data::Dict{String, Any})

Create a new record in the table or with a specific ID.

  • what: Table name (String or Table) or record ID (RecordID)
  • data: Record fields as a Dict

Returns the created record(s) as a Dict or Vector of Dicts.

source
create(client, ::Type{T}, what, data)

Create a record and return it as a typed struct T.

Examples

stream = SurrealDB.create(db, Stream, "stream", Dict("name" => "new"))
source
SurrealDB.selectFunction
select(client, what) -> Any

Select all records from a table or fetch a specific record by ID.

Returns a Vector of records when what is a table, or a single record (Dict) when what is a record ID. Returns an empty vector / nothing when the target does not exist.

See also: create, update, delete.

source
select(client, ::Type{T}, what)

Select a record or table and map results to typed Julia struct T.

For table selects, returns Vector{T}. For record selects, returns T.

Examples

struct Stream
    id::SurrealDB.RecordID
    name::String
end
StructTypes.StructType(::Type{Stream}) = StructTypes.Struct()

all_streams = SurrealDB.select(db, Stream, "stream")
one_stream = SurrealDB.select(db, Stream, "stream:abc")
source
SurrealDB.updateFunction
update(client, what, data) -> Any

Replace the contents of a record (or every record in a table) with data. Existing fields not present in data are removed; for partial updates use merge instead.

  • what: Table name or record ID
  • data: Replacement record contents (Dict)

Returns the updated record(s).

See also: merge, upsert, patch.

source
SurrealDB.deleteFunction
delete(client, what) -> Any

Delete a record or every record in a table.

  • what: Table name or record ID

Returns the deleted record(s). Deleting a nonexistent record is not an error on SurrealDB v3 (returns nothing).

See also: select, create.

source
SurrealDB.insertFunction
insert(client, table, data) -> Any

Insert one or many records into a table. Unlike create, data may be a single Dict or a Vector of Dicts for batch inserts; ids are auto-assigned when not provided.

  • table: Table name (String or Table)
  • data: Single Dict or Vector of Dicts

Returns the inserted record(s).

See also: create, insert_relation.

source
SurrealDB.upsertFunction
upsert(client, what, data) -> Any

Create the record if it does not exist, otherwise replace it. Same payload shape as update; the difference is that update on a missing record may not create it on all SurrealDB versions.

See also: update, merge.

source
SurrealDB.mergeFunction
merge(client, what, data) -> Any

Partially update a record by merging data into the existing record. Fields present in data overwrite existing fields; fields absent are preserved (unlike update which replaces the whole record).

  • what: Table name or record ID
  • data: Partial record contents (Dict)

See also: update, patch.

source
SurrealDB.relateFunction
relate(client, from, edge, to; data=nothing) -> Any
relate(client, rel::Relationship) -> Any

Create a graph edge from from to to via edge. The flat-arg form is the canonical first-class signature; the Relationship form is convenient for storing/passing pre-built edges.

  • from: source record id (RecordID or "table:id" string)
  • edge: edge table (Table or String) or specific edge record id
  • to: target record id
  • data: optional Dict of edge fields

Returns the created edge record.

Examples

SurrealDB.relate(db, "person:john", "knows", "person:jane";
                 data=Dict("met" => "2024-01-01"))

# Or via the bulk struct
rel = Relationship("person:john", Table("knows"), "person:jane",
                   Dict("met" => "2024-01-01"))
SurrealDB.relate(db, rel)

See also: insert_relation, Relationship.

source
SurrealDB.insert_relationFunction
insert_relation(client, relationship::Relationship) -> Any

Insert a graph edge defined by a Relationship. Equivalent to SurrealQL INSERT RELATION INTO <table> { in, out, ... }.

Differs from relate in that insert_relation is intended for batch / seeded edges; relate is the canonical first-class edge primitive.

See also: relate, Relationship.

source
SurrealDB.patchFunction
patch(client, what, patches::Vector{Dict{String, Any}})

Apply JSON Patch operations to a record.

Examples

SurrealDB.patch(db, "user:1", [
    Dict("op" => "replace", "path" => "/name", "value" => "New Name"),
    Dict("op" => "add", "path" => "/tags/0", "value" => "new-tag")
])
source
SurrealDB.patch_removeFunction
patch_remove(client, what, path::String)

Convenience wrapper around patch that issues a single JSON-Patch remove operation at path.

source
SurrealDB.patch_replaceFunction
patch_replace(client, what, path::String, value)

Convenience wrapper around patch that issues a single JSON-Patch replace operation at path.

source
SurrealDB.runFunction
run(client, fn_name::String, args=Any[]; version=nothing) -> Any

Invoke a SurrealDB function — builtin (type::*, string::*, ...) or user-defined (fn::*).

  • fn_name: Function name including namespace, e.g. "fn::greet" or "type::is::array"
  • args: Positional args as a Vector
  • version: Optional semver string for versioned user functions

Examples

SurrealDB.run(db, "type::is::array", [[1, 2, 3]])  # → true
SurrealDB.run(db, "fn::greet", ["world"])
source
SurrealDB.pingFunction
ping(client::SurrealClient) -> Bool

Send a lightweight RPC ping. Returns true if the server responds. Backs the keepalive timer; exposed for callers who want a manual liveness check without health()'s trivial-query fallback.

source
SurrealDB.let!Function
let!(client, key::String, value)

Set a session variable. These variables can be referenced in SurrealQL queries using $key syntax.

Examples

SurrealDB.let!(db, "min_age", 18)
result = SurrealDB.query(db, "SELECT * FROM user WHERE age > $min_age")
source

Live queries

SurrealDB.liveFunction
live(client, table; diff=false)

Start a live query subscription on a table.

Returns a LiveSubscription with a channel field you can iterate over to receive real-time notifications.

  • table: Table name (String or Table)
  • diff: If true, notifications include the diff between old and new values

Examples

sub = SurrealDB.live(db, "stream")
for notification in sub.channel
    println("Action: ", notification["action"])
    println("Data: ", notification["data"])
    break  # or loop forever
end
SurrealDB.kill!(sub)
source
SurrealDB.subscribeFunction
subscribe(sub::LiveSubscription) -> LiveSubscription

Register an additional consumer on sub's server-side live query. The returned subscription shares query_id with the input but holds a fresh channel; both channels receive every notification (fan-out at the SDK level).

kill!(original_sub) (or kill!(client, query_id)) tears down ALL subscribers sharing the UUID — per-consumer teardown is not supported. WS-only.

sub  = SurrealDB.live(db, "stream")
sub2 = SurrealDB.subscribe(sub)
@async for n in sub.channel;  process(n); end    # consumer A
@async for n in sub2.channel; log(n);     end    # consumer B
SurrealDB.kill!(sub)                              # both channels close
source
SurrealDB.kill!Function
kill!(client, query_id::String)

Terminate a live query by its UUID. If a LiveSubscription handle was registered for this id (i.e. created via live), its active flag is flipped to false and its channel is closed so consumers iterating it observe the termination.

source
kill!(sub::LiveSubscription)

Terminate a live query subscription. Delegates to kill! by id, which flips sub.active and closes the channel.

source
SurrealDB.LiveSubscriptionType
LiveSubscription(query_id, channel, client)

A live query subscription. Iterate over sub.channel (or sub directly) to receive LiveNotification events. Call kill!(sub) to terminate.

Fields:

  • query_id::String: UUID string identifying the live query on the server
  • channel::Channel: receives LiveNotification events
  • active::Bool: subscription state
source
SurrealDB.LiveNotificationType
LiveNotification(action, query_id, record, result, session)

One live-query event delivered to a LiveSubscription channel. Subtype of AbstractDict{String, Any} so legacy n["action"] access keeps working alongside the typed n.action form.

Fields:

  • action::String: "CREATE", "UPDATE", or "DELETE" ("KILLED" events are dropped by the dispatcher)
  • query_id::String: live UUID matching sub.query_id
  • record::Union{String, Nothing}: affected record id, e.g. "users:abc"
  • result::Any: payload — the record on CREATE/UPDATE, the pre-delete record on DELETE
  • session::Union{String, Nothing}: v3 session id; nothing on v2
source

Transactions and sessions

SurrealDB.begin!Function
begin!(client)

Start a new transaction. All subsequent operations within the transaction are isolated until commit! or cancel! is called.

On SurrealDB v3+ remote connections, begin!/commit!/cancel! RPC methods may return "Expected transaction UUID". Use raw SurrealQL instead:

SurrealDB.query(db, "BEGIN TRANSACTION; ...; COMMIT TRANSACTION;")
source
begin!(session::SurrealSession) -> SurrealTransaction

Start a transaction within a v3+ session. Returns a SurrealTransaction handle; pass it to commit! or cancel! to finalize.

source
SurrealDB.commit!Function
commit!(client)

Commit the active transaction, persisting all changes made within it. For v3+ remote connections, prefer raw SurrealQL COMMIT TRANSACTION;.

source
commit!(txn::SurrealTransaction)

Commit a v3+ session transaction. Flips txn.closed = true even if the RPC throws, so a stale handle can't be re-used.

source
SurrealDB.cancel!Function
cancel!(client)

Cancel / rollback the active transaction, discarding all changes made within it. For v3+ remote connections, prefer raw SurrealQL CANCEL TRANSACTION;.

source
cancel!(txn::SurrealTransaction)

Cancel/rollback a v3+ session transaction. Flips txn.closed = true even if the RPC throws.

source
SurrealDB.SurrealTransactionType
SurrealTransaction

A v3+ interactive transaction handle. Returned by begin!(session). Call commit!(txn) or cancel!(txn) to finalize; either flips txn.closed = true so a stale handle can't be re-committed against a server-side transaction that no longer exists.

Matches the wrapper pattern used by surrealdb-go (Transaction struct with closed bool, external/sdk-refs/go/transaction.go:24) and surrealdb-js (SurrealTransaction extends SurrealQueryable, external/sdk-refs/js/.../api/transaction.ts:13).

source
SurrealDB.attach!Function
attach!(client) -> SurrealSession

Create a new ephemeral session on the server (SurrealDB v3+) and return a SurrealSession wrapper. The session is independent: its own namespace, database, auth, and variables. Close with close!.

Matches the wrapped-session API used by surrealdb-go (db.Attach), surrealdb-py (AsyncSurrealSession / BlockingSurrealSession), and surrealdb-js (newSession).

WebSocket-only (not supported on HTTP connections).

source
SurrealDB.sessionsFunction
sessions(client)

List active session UUIDs on the server (SurrealDB v3+).

Returns Vector{UUID}.

source
SurrealDB.SurrealSessionType
SurrealSession

A v3+ server-side session wrapping a SurrealClient.

Fields:

  • client::SurrealClient — the underlying connection
  • session_id::UUID — the server-assigned session identifier

All operations on this session are scoped to the session's namespace, database, auth, and variables.

source

Import / Export

SurrealDB.export_dbFunction
export_db(client::SurrealClient, filepath::String)

Export the current namespace and database to a file.

source
SurrealDB.import_dbFunction
import_db(client::SurrealClient, filepath::String)

Import data from a file into the current namespace and database.

source