Skip to content

feat: add table branch support#3490

Merged
brendanclement merged 17 commits into
mainfrom
feat/table-branches
Jun 8, 2026
Merged

feat: add table branch support#3490
brendanclement merged 17 commits into
mainfrom
feat/table-branches

Conversation

@brendanclement

@brendanclement brendanclement commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

Description

Adds first-class support for table branches across the Rust core and the Python and TypeScript SDKs.

Rust

use lance::dataset::refs::Ref;

// Create a branch from main and write to it — main is untouched.
let exp = table.create_branch("exp", Ref::Version(None, None)).await?;
exp.add(batches).await?;

// Reopen the branch later: check out from a table, or open it directly.
let exp = table.checkout_branch("exp").await?;
let exp = db.open_table("items").branch("exp").execute().await?;

let branches = table.list_branches().await?;
table.delete_branch("exp").await?;

Python

# Create a branch from main and write to it
branch = await table.branches.create("exp", from_ref="main")
await branch.add(data)

# Reopen the branch later: check out from a table, or open it directly.
branch = await table.branches.checkout("exp")
branch = await db.open_table("items", branch="exp")

await table.branches.list()
await table.branches.delete("exp")

TypeScript

const branches = await table.branches();

// Create a branch from main and write to it
const branch = await branches.create("exp");
await branch.add(data);

// Reopen the branch later: check out from a table, or open it directly.
const checkedOut = await branches.checkout("exp");
const opened = await db.openTable("items", undefined, { branch: "exp" });

await branches.list();
await branches.delete("exp");

Testing

  • Added unit tests
  • ran smoke tests against python and typescript sdks on local machine

Next steps

  • Add RemoteTable support
  • Add Branch Comparison support
  • Merge Branching support

@github-actions github-actions Bot added enhancement New feature or request Python Python SDK Rust Rust related issues labels Jun 3, 2026
@brendanclement brendanclement added the typescript Typescript / javascript label Jun 3, 2026
@brendanclement

Copy link
Copy Markdown
Contributor Author

@claude review once

Comment thread python/python/lancedb/table.py Outdated
@brendanclement

Copy link
Copy Markdown
Contributor Author

@claude review once

Comment thread python/python/lancedb/table.py
Comment thread nodejs/src/table.rs Outdated
@brendanclement

Copy link
Copy Markdown
Contributor Author

@claude review once

1 similar comment
@brendanclement

Copy link
Copy Markdown
Contributor Author

@claude review once

@brendanclement
brendanclement marked this pull request as ready for review June 3, 2026 17:10

@claude claude Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Claude Code Review

This repository is configured for manual code reviews. Comment @claude review to trigger a review and subscribe this PR to future pushes, or @claude review once for a one-time review.

Tip: disable this comment in your organization's Code Review settings.

@mintlify

mintlify Bot commented Jun 3, 2026

Copy link
Copy Markdown

Docs PR opened: lancedb/docs#263

Added a Branches page under Table operations covering creating, listing, checking out, and deleting table branches across Python, TypeScript, and Rust.

Once this PR is merged, we'll do a second pass to capture any additional changes and update the docs PR.

Comment thread python/python/lancedb/namespace.py
Comment thread rust/lancedb/src/table.rs
@brendanclement

Copy link
Copy Markdown
Contributor Author

@claude review once

Comment thread python/python/tests/test_table.py

@wjones127 wjones127 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The API looks really well designed. I like this.

There are a few behavior / testing issues I think we need to address before we merge this.

Comment on lines +763 to +764
#[tokio::test]
async fn test_as_branch_is_writable_and_tracked() {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue(blocking): one test I would like to see is what happens to a branch handle if it's concurrently updated? Does the branch handle track new writes to the branch? Either way we go, I think the behavior should be asserted in a test.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've added a test here to document the desired behaviour. A branch handle will track new writes to its branch at its read_consistency_interval.

Comment thread python/python/tests/test_table.py Outdated


def test_branches(tmp_path):
db = lancedb.connect(tmp_path)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue(blocking): the default for read_consistency_interval is None, which actually makes this test less useful. I would recommend setting this to zero for these kinds of tests:

Suggested change
db = lancedb.connect(tmp_path)
db = lancedb.connect(tmp_path, read_consistency_interval=timedelta(0))

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good catch, changed to 0

@wjones127 wjones127 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Excellent. Thank you!

@brendanclement
brendanclement merged commit 53517b3 into main Jun 8, 2026
29 checks passed
@brendanclement
brendanclement deleted the feat/table-branches branch June 8, 2026 23:26
@mintlify

mintlify Bot commented Jun 8, 2026

Copy link
Copy Markdown

Docs PR opened: lancedb/docs#267

Added a Branches section to the versioning guide covering create, checkout, list, and delete across Python, TypeScript, and Rust.

brendanclement added a commit that referenced this pull request Jun 9, 2026
### Description

Stacked on #3490. Adds an optional version to branch checkout across the
Rust core and the Python and TypeScript SDKs, so you can open a specific
version on a branch ("version V of branch B"), not just the branch's
latest version

Rust

```rust
// Open version 3 of branch "exp" (a read-only view): check out from an
// existing table, or open it directly from the connection.
let exp_v3 = table.checkout_branch("exp", Some(3)).await?;
let exp_v3 = db.open_table("items").branch("exp").version(3).execute().await?;
// checkout_latest re-attaches to the branch's writable HEAD.
exp_v3.checkout_latest().await?;

// With no branch, a version opens main at that version.
let main_v3 = db.open_table("items").version(3).execute().await?;
```

Python

```python
# Open version 3 of branch "exp" (a read-only view): check out from an
# existing table, or open it directly from the connection.
branch_v3 = await table.branches.checkout("exp", version=3)
branch_v3 = await db.open_table("items", branch="exp", version=3)
# checkout_latest re-attaches to the branch's writable HEAD.
await branch_v3.checkout_latest()

# With no branch, a version opens main at that version.
main_v3 = await db.open_table("items", version=3)
```

TypeScript

```typescript
// Open version 3 of branch "exp" (a read-only view): check out from an
// existing table, or open it directly from the connection.
const branchV3 = await (await table.branches()).checkout("exp", 3);
const opened = await db.openTable("items", undefined, { branch: "exp", version: 3 });
// checkoutLatest re-attaches to the branch's writable HEAD.
await branchV3.checkoutLatest();

// With no branch, a version opens main at that version.
const mainV3 = await db.openTable("items", undefined, { version: 3 });
```

### Testing
- Added unit tests (Rust, Python sync + async, TypeScript):
branch-scoped resolution at a version number shared with `main` and with
another branch, read-only enforcement on a pinned handle,
`checkout_latest` recovery to the branch's HEAD, fork-point reads, and
the nonexistent-version/branch error paths.
- Ran smoke tests against the Python and TypeScript SDKs on local
machine.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request Python Python SDK Rust Rust related issues typescript Typescript / javascript

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants