Select an Exact State
Pin a branch head or resolve a tag to one commit, then read Tables at that commit.
A training run that reads frames on Monday and again on Tuesday should see
the same rows, even if someone appends in between. To guarantee that, resolve
your branch or tag to one commit
ID up front and read every Table through it. Table versions never change, so
the commit ID is also the record that lets you rerun the job later.
Before you start
- A Project
demowith the Tableframes. - An access token in
$SPIRAL_TOKEN. See authentication. - For Rust, a configured
Client. See the Rust SDK.
Pin a branch head
Read the branch to get its stable ID and its current head commit.
head = client.project("demo").branch("experiment")
print(f"experiment head: {head.commit_id}")
for page in client.catalog.read_state_pages("demo", head.commit_id):
for resource in page.resources:
descriptor = resource.descriptor
print(f"{descriptor.kind} {descriptor.resource_id} at version {resource.version_id}")The head commit stays valid after the branch moves. Use it for every read in the same workflow.
Resolve a tag to a commit
Send a commit selector. A selector names a commit, a branch, or a tag. The Catalog resolves it once and returns the commit ID.
request = CatalogResolveCommitRequest(selector=CatalogCommitSelector(tag=CatalogTagTarget(tag="training-v7")))
resolved = client.catalog.resolve_commit("demo", request)
print(f"training-v7 is {resolved.commit_id}")For a branch, send {"type": "branch", "branch": {"branch": "main"}}. For a
commit, send {"type": "commit", "commit": {"commitId": "..."}}. Relative
expressions such as main~3 are not supported.
The Rust SDK does not resolve tags. Resolve the tag with another client, then use the commit ID in Rust.
Read Tables at the commit
Resolve a Resource path at the commit to get its exact version:
tables = client.project("demo").branch("main")
on_branch = tables.table("frames@experiment")
at_commit = tables.table(f"frames@c{commit}")
print(f"experiment selects {on_branch.version_id}")
print(f"the commit selects {at_commit.version_id}")
rows = at_commit.scan(limit=10).to_table().num_rowsIn Python and Rust, a Table address has an optional reference after @:
| Address | Selects |
|---|---|
frames | The default snapshot of the Table session |
frames@experiment | The head of experiment, pinned on first use |
frames@c<commit> | The Table at one Project commit |
frames@v<version> | One exact Table version |
A commit or version reference is c or v followed by the ID as 32 lowercase
hexadecimal digits, without dashes. HTTP returns IDs with dashes, so remove them
first. See Addresses.
Verify the result
Read frames@c<commit> before and after another writer publishes on the
branch. Both reads return the same Table version. A new Table session with a
branch address, such as frames@main, returns the new head.
Troubleshooting
| Error | Cause |
|---|---|
BranchNotFound | The branch name does not exist, or the branch was deleted. |
TagNotFound | The tag name does not exist in this Project. |
CommitNotFound | The commit ID does not belong to this Project. |
resource not found (Rust) | The path has no binding at the selected commit. |
To read the Tables with SQL, register the Table session with DataFusion.