Skip to content

API Reference

/

Values

Null

SurrealDB has two values for a field that holds nothing. NONE means that the field is not there, and NULL means that the field is there and holds a null value. Python has only None, so the SDK uses None for NONE and the Null object for NULL. This page documents Null and how the two values behave when you read and write records.

Import
from surrealdb import Null, NullType

Source: null.py

PythonSurrealDBRead back as
NoneNONENone. A field that is NONE is not in the record at all.
NullNULLNull

Null is the only instance of NullType. Calling NullType() returns the same object, and copying or pickling Null gives Null again, so a test with is Null always works.

A NULL field reads as Null, so a record that you read, change and write back keeps the field as NULL. A field set to None is sent as NONE, which removes the field from the record.

from surrealdb import Null, RecordID, Surreal

with Surreal("ws://localhost:8000") as db:
    db.signin({"username": "root", "password": "secret"})
    db.use("surrealdb", "docs")

    tobie = RecordID("person", "tobie")
    db.create(tobie, {"name": "Tobie", "nickname": Null})

    person = db.select(tobie).execute()
    person["name"] = "Tobie Morgan"
    saved = db.update(tobie, person)
    print(saved["nickname"])

    saved = db.update(tobie, {"name": "Tobie", "nickname": None})
    print("nickname" in saved)
Output
Null
False

The first update() writes the record back with its NULL field. The second sends None for the field, so the stored record no longer has a nickname.

Null is falsy, like None, so if not value: treats both as empty. Null is not equal to None, so a test with is None or == None does not find a NULL field. Where a field can hold either value, test for both.

from surrealdb import Null

print(bool(Null), Null == None, Null is None)

nickname = Null
if nickname is None or nickname is Null:
    print("no nickname")
Output
False False False
no nickname

repr(Null) is Null. The object is immutable: setting an attribute on it raises AttributeError.

A schemafull field accepts only the empty value that its type names. option<T> accepts NONE, and a union with null accepts NULL.

Field typeNone (NONE)Null (NULL)
stringRefusedRefused
option<string>Accepted, the field is left outRefused
string | nullRefusedAccepted
option<string | null>Accepted, the field is left outAccepted

A refused value raises a ServerError that names the field and the type it expected.

  • An open end of a Range is Null. Range(None, BoundExcluded(10)) stores Null as its start, and a range read back has Null there too.

  • In use(), None keeps the current namespace or database, and Null clears it: db.use(database=Null) leaves the connection with no database selected.

Pydantic has no built-in schema for NullType. To read a field that can hold NULL into a model, add NullType to the field's annotation and allow arbitrary types on the model. Without NullType in the annotation, a NULL value fails validation for a field such as str | None.

from pydantic import BaseModel, ConfigDict
from surrealdb import Null, NullType

class Person(BaseModel):
    model_config = ConfigDict(arbitrary_types_allowed=True)

    name: str
    nickname: str | NullType | None = None

person = Person(name="Tobie", nickname=Null)
print(person.nickname is Null)
Output
True

Was this page helpful?