From f601f1abd2f7df5e92d57b447cd3b60b4c05065c Mon Sep 17 00:00:00 2001 From: "mintlify[bot]" <109931778+mintlify[bot]@users.noreply.github.com> Date: Mon, 15 Jun 2026 22:11:57 +0000 Subject: [PATCH] docs: document table branches in versioning guide --- docs/snippets/tables.mdx | 6 +++++ docs/tables/versioning.mdx | 53 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+) diff --git a/docs/snippets/tables.mdx b/docs/snippets/tables.mdx index baee1cb..5c531e1 100644 --- a/docs/snippets/tables.mdx +++ b/docs/snippets/tables.mdx @@ -122,6 +122,8 @@ export const PyVersioningRollback = "table.restore(version_after_mod)\nversions export const PyVersioningTags = "# Create a tag pointing at a specific version\ntable.tags.create(\"baseline\", 1)\ntable.tags.create(\"with-edits\", table.version)\n\n# List all tags on this table\nprint(table.tags.list())\n\n# Look up the version a tag points at\nprint(table.tags.get_version(\"baseline\"))\n\n# Move an existing tag to a different version\ntable.tags.update(\"baseline\", 2)\n\n# Check out a version by tag name\ntable.checkout(\"baseline\")\nprint(table.version)\n\n# Delete a tag (does not delete the underlying version)\ntable.tags.delete(\"with-edits\")\n\n# Return to the latest version\ntable.checkout_latest()\n"; +export const PyVersioningBranches = "# Fork a new branch from the latest version of main\nexperiment = table.branches.create(\"experiment\")\nprint(experiment.current_branch()) # \"experiment\"\n\n# Writes on the branch handle do not affect main\nexperiment.add([{\"author\": \"Maya\", \"quote\": \"draft idea\"}])\n\n# List all branches on the table\nprint(table.branches.list())\n\n# Reopen an existing branch later (writable handle that tracks the branch tip)\nexperiment = table.branches.checkout(\"experiment\")\n\n# Pin a branch to a specific version (read-only view of that version)\nsnapshot = table.branches.checkout(\"experiment\", version=2)\n\n# Open a branch directly from the connection\nexperiment = db.open_table(\"my_table\", branch=\"experiment\")\n\n# Delete a branch when you're done with it\ntable.branches.delete(\"experiment\")\n"; + export const PyVersioningUpdateData = "table.update(where=\"author='Richard'\", values={\"author\": \"Richard Daniel Sanchez\"})\nrows_after_update = table.count_rows(\"author = 'Richard Daniel Sanchez'\")\nprint(f\"Rows updated to Richard Daniel Sanchez: {rows_after_update}\")\n"; export const TsAddColumnsCalculated = "// Add a discounted price column (10% discount)\nawait schemaAddTable.addColumns([\n {\n name: \"discounted_price\",\n valueSql: \"cast((price * 0.9) as float)\",\n },\n]);\n"; @@ -218,6 +220,8 @@ export const TsVersioningRollback = "await table.checkout(versionAfterMod);\nawa export const TsVersioningTags = "const tags = await tagsTable.tags();\n\n// Create a tag pointing at a specific version\nawait tags.create(\"baseline\", 1);\nawait tags.create(\"with-edits\", await tagsTable.version());\n\n// List all tags on this table\nconsole.log(await tags.list());\n\n// Look up the version a tag points at\nconsole.log(await tags.getVersion(\"baseline\"));\n\n// Move an existing tag to a different version\nawait tags.update(\"baseline\", 2);\n\n// Check out a version by tag name\nawait tagsTable.checkout(\"baseline\");\nconsole.log(await tagsTable.version());\n\n// Delete a tag (does not delete the underlying version)\nawait tags.delete(\"with-edits\");\n\n// Return to the latest version\nawait tagsTable.checkoutLatest();\n"; +export const TsVersioningBranches = "const branches = await table.branches();\n\n// Fork a new branch from the latest version of main\nconst experiment = await branches.create(\"experiment\");\nconsole.log(experiment.currentBranch); // \"experiment\"\n\n// Writes on the branch handle do not affect main\nawait experiment.add([{ author: \"Maya\", quote: \"draft idea\" }]);\n\n// List all branches on the table\nconsole.log(await branches.list());\n\n// Reopen an existing branch later (writable handle that tracks the branch tip)\nconst tracking = await branches.checkout(\"experiment\");\n\n// Pin a branch to a specific version (read-only view of that version)\nconst snapshot = await branches.checkout(\"experiment\", 2);\n\n// Delete a branch when you're done with it\nawait branches.delete(\"experiment\");\n"; + export const TsVersioningUpdateData = "await table.update({\n where: \"author = 'Richard'\",\n values: { author: \"Richard Daniel Sanchez\" },\n});\nconst rowsAfterUpdate = await table.countRows(\n \"author = 'Richard Daniel Sanchez'\",\n);\nconsole.log(`Rows updated to Richard Daniel Sanchez: ${rowsAfterUpdate}`);\n"; export const RsAddColumnsCalculated = "// Add a discounted price column (10% discount)\nschema_add_table\n .add_columns(\n NewColumnTransform::SqlExpressions(vec![(\n \"discounted_price\".to_string(),\n \"cast((price * 0.9) as float)\".to_string(),\n )]),\n None,\n )\n .await\n .unwrap();\n"; @@ -318,5 +322,7 @@ export const RsVersioningRollback = "table.checkout(version_after_mod).await.unw export const RsVersioningTags = "let mut tags = tags_table.tags().await.unwrap();\n\n// Create a tag pointing at a specific version\ntags.create(\"baseline\", 1).await.unwrap();\nlet current_version = tags_table.version().await.unwrap();\ntags.create(\"with-edits\", current_version).await.unwrap();\n\n// List all tags on this table\nlet all_tags = tags.list().await.unwrap();\nprintln!(\"Tags: {:?}\", all_tags);\n\n// Look up the version a tag points at\nlet baseline_version = tags.get_version(\"baseline\").await.unwrap();\nprintln!(\"baseline -> v{}\", baseline_version);\n\n// Move an existing tag to a different version\ntags.update(\"baseline\", 2).await.unwrap();\n\n// Check out a version by tag name (separate method in Rust)\ntags_table.checkout_tag(\"baseline\").await.unwrap();\nprintln!(\"Current version: {}\", tags_table.version().await.unwrap());\n\n// Delete a tag (does not delete the underlying version)\ntags.delete(\"with-edits\").await.unwrap();\n\n// Return to the latest version\ntags_table.checkout_latest().await.unwrap();\n"; +export const RsVersioningBranches = "// Fork a new branch from the latest version of main\nlet experiment = table.create_branch(\"experiment\", None, None).await.unwrap();\nprintln!(\"{:?}\", experiment.current_branch()); // Some(\"experiment\")\n\n// List all branches on the table\nlet all_branches = table.list_branches().await.unwrap();\nprintln!(\"Branches: {:?}\", all_branches);\n\n// Reopen an existing branch later (writable handle that tracks the branch tip)\nlet tracking = table.checkout_branch(\"experiment\", None).await.unwrap();\n\n// Pin a branch to a specific version (read-only view of that version)\nlet snapshot = table.checkout_branch(\"experiment\", Some(2)).await.unwrap();\n\n// Delete a branch when you're done with it\ntable.delete_branch(\"experiment\").await.unwrap();\n"; + export const RsVersioningUpdateData = "table\n .update()\n .only_if(\"author = 'Richard'\")\n .column(\"author\", \"'Richard Daniel Sanchez'\")\n .execute()\n .await\n .unwrap();\nlet rows_after_update = table\n .count_rows(Some(\"author = 'Richard Daniel Sanchez'\".to_string()))\n .await\n .unwrap();\nprintln!(\n \"Rows updated to Richard Daniel Sanchez: {}\",\n rows_after_update\n);\n"; diff --git a/docs/tables/versioning.mdx b/docs/tables/versioning.mdx index 61fd91e..0dcde53 100644 --- a/docs/tables/versioning.mdx +++ b/docs/tables/versioning.mdx @@ -35,6 +35,9 @@ import { PyVersioningTags as VersioningTags, TsVersioningTags as TsVersioningTags, RsVersioningTags as RsVersioningTags, + PyVersioningBranches as VersioningBranches, + TsVersioningBranches as TsVersioningBranches, + RsVersioningBranches as RsVersioningBranches, RsVersioningMakeQuotesReader as RsVersioningMakeQuotesReader, } from '/snippets/tables.mdx'; @@ -218,6 +221,56 @@ Deleting a tag only removes the label, not the version it points to. After deletion, the underlying table version becomes eligible for cleanup again. +## Branches + +Branches are isolated, writable lines of history forked from another branch +(or a specific version of one). Use them when you need to experiment with +schema or data changes, run an A/B compaction strategy, or stage a backfill +without affecting readers on `main`. Conceptually they sit next to tags: +**tags label a single version**, while **branches let history diverge** from +that point. + +The branch manager supports the standard operations — `create`, `list`, +`checkout`, `delete` — and `checkout` / `create` return a new table handle +scoped to the branch. Writes on that handle do not touch `main`. The +original handle keeps pointing at the branch it was opened on, which is +reported by `current_branch()` (`null` / `None` for `main`). + + + + {VersioningBranches} + + + + {TsVersioningBranches} + + + + {RsVersioningBranches} + + + +In Python, you can also open a branch directly from the connection by +passing `branch=` to `open_table()`. Combine it with `version=` to open a +read-only handle pinned to a specific version on that branch: + +```python +# Latest version of the experiment branch (writable) +experiment = db.open_table("my_table", branch="experiment") + +# Pinned to v3 of the experiment branch (read-only) +snapshot = db.open_table("my_table", branch="experiment", version=3) +``` + + +Each branch handle has its own freshness state and version pin, so reopening +a branch on a new connection — or restoring one from a pickled handle — +keeps you on the branch instead of silently reverting to `main`. + +Branches are supported by tables backed by the Lance format directly and by +remote tables served by LanceDB Enterprise. + + ## Delete Data From the Table Let's demonstrate how deletions also create new versions: