Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file modified .github/demos/rename.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
12 changes: 7 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@ Python data pipelines, and it keeps its state in append-only tables in your own
external state database, no manifest files and no paid tier.

<p align="center">
<img src="https://raw.githubusercontent.com/chio-labs/sqlbuild/main/.github/demos/rename.gif" alt="Moving and renaming an incremental model: sqb plan migrates the existing table instead of rebuilding it" width="100%">
<img src="https://raw.githubusercontent.com/chio-labs/sqlbuild/main/.github/demos/rename.gif" alt="Moving and renaming an incremental model with sqb mv: sqb plan migrates the existing table instead of rebuilding it" width="100%">
</p>

Move an incremental model to a new folder and name, and `sqb plan` migrates its table instead of
rebuilding it.
Move an incremental model to a new folder and name with `sqb mv`, and `sqb plan` migrates its table
instead of rebuilding it.

## Quick start

Expand Down Expand Up @@ -62,9 +62,11 @@ The playground runs on local DuckDB, with no warehouse credentials.

### Change it without rebuilding everything

- **Renames keep their history.** Rename or move an incremental or snapshot model and SQLBuild
- **Renames keep their history.** [`sqb rename` and `sqb mv`](https://sqlbuild.com/docs/cli/rename/)
update every reference, and the next build
[migrates](https://sqlbuild.com/docs/concepts/models/migrations/) the existing table instead of
rebuilding it.
rebuilding it. The old name keeps working through a compatibility view.
`sqb rename column:<model>.<column>` renames an incremental model's column in place.
- **Replay on change.** When a model's SQL changes, choose how far back to reprocess, from only the
new data to the last 14 days to a full rebuild, with
[`replay_on_change`](https://sqlbuild.com/docs/concepts/incremental/#replay-on-change).
Expand Down
19 changes: 18 additions & 1 deletion website/examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,20 @@ rm models/weekly_revenue.sql
sqb janitor
```

## Step 07: rename

`waffle-shop` shows the state after the rename. Give the model its old name, build it, then rename
it back:

```bash
cd waffle-shop
mv models/marts/daily_order_rollup.sql models/marts/daily_activity_rollup.sql
sed -i 's/daily_order_rollup/daily_activity_rollup/g' models/marts/hourly_activity_with_daily_context.sql
sqb build
sqb rename model:daily_activity_rollup daily_order_rollup
sqb plan
```

## Hero: move and rename

`hero-shop` shows the state after the move. The model started as `models/marts/revenue.sql`:
Expand All @@ -51,6 +65,9 @@ cd hero-shop
mkdir -p models/marts
mv models/finance/daily_revenue.sql models/marts/revenue.sql
sqb build
mv models/marts/revenue.sql models/finance/daily_revenue.sql
sqb mv model:revenue models/finance/daily_revenue.sql
sqb plan
```

`sqb rename` and `sqb mv` add `migrate_from` to the model header; the example projects leave it out,
so they can be set up again.
10 changes: 9 additions & 1 deletion website/examples/hero-shop/models/finance/daily_revenue.sql
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,14 @@ MODEL (
cursor revenue_date,
cursor_type timestamp,
cursor_grain day,
cursor_inputs (
payments paid_at,
),
);

SELECT CAST('2026-04-01' AS DATE) AS revenue_date, 2850 AS total_revenue_cents
SELECT
CAST(paid_at AS DATE) AS revenue_date,
SUM(amount_cents) AS total_revenue_cents
FROM __seed("payments")
GROUP BY
CAST(paid_at AS DATE)
6 changes: 6 additions & 0 deletions website/examples/hero-shop/seeds/payments.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
payment_id,paid_at,amount_cents
1,2026-04-01 09:12:00,1250
2,2026-04-01 13:40:00,1600
3,2026-04-02 10:05:00,900
4,2026-04-02 18:22:00,2100
5,2026-04-03 11:47:00,1450
10 changes: 10 additions & 0 deletions website/examples/hero-shop/seeds/payments.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
seeds:
- name: payments
description: Successful payments.
columns:
- name: payment_id
type: INTEGER
- name: paid_at
type: TIMESTAMP
- name: amount_cents
type: INTEGER
Binary file modified website/public/assets/og-sqlbuild.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
25 changes: 17 additions & 8 deletions website/public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
<meta property="og:image" content="https://sqlbuild.com/assets/og-sqlbuild.png" />
<meta property="og:image:width" content="1200" />
<meta property="og:image:height" content="630" />
<meta property="og:image:alt" content="SQLBuild: the refactorable warehouse. A model file is moved and renamed." />
<meta property="og:image:alt" content="SQLBuild: the refactorable warehouse. sqb rename renames a model, and sqb plan migrates its table from prod.revenue to prod.daily_revenue. History kept. Nothing rebuilt." />
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:image" content="https://sqlbuild.com/assets/og-sqlbuild.png" />
<link rel="icon" type="image/png" href="assets/icon.png" />
Expand Down Expand Up @@ -76,13 +76,13 @@ <h1>The refactorable warehouse</h1>
<div
class="terminal hero-visual"
role="img"
aria-label="A model file is moved and renamed, and sqb plan shows a migration of the existing table instead of a rebuild."
><span class="hv-stack"><span class="hv-a"><span class="tree"><span class="dim">models</span>
aria-label="sqb mv moves and renames a model file, and sqb plan shows a migration of the existing table instead of a rebuild, with a view keeping the old name working."
><span class="hv-l hv-l0"><span class="cmd">sqb mv model:revenue<span class="hv-break"> </span>models/finance/daily_revenue.sql</span></span><span class="hv-stack"><span class="hv-a"><span class="tree"><span class="dim">models</span>
<span class="dim">└──</span> marts
<span class="dim">└──</span> revenue.sql</span></span><span class="hv-b"><span class="tree"><span class="dim">models</span>
<span class="dim">└──</span> finance
<span class="dim">└──</span> <span class="info">daily_revenue.sql</span></span></span></span>
<span class="hv-l hv-l1"><span class="cmd">sqb plan</span></span><span class="hv-l hv-l2"><span class="strong">Migrations</span> <span class="dim">(1)</span></span><span class="hv-l hv-l3"><span class="tree"><span class="dim">└──</span></span> daily_revenue <span class="info strong">migrate</span><span class="hv-wide"> <span class="dim">prod.revenue -&gt;</span> prod.daily_revenue</span></span><span class="hv-l hv-l4"><span class="tree"> <span class="dim">├──</span></span> <span class="dim">compatibility</span> <span class="ok">compatible</span></span><span class="hv-l hv-l5"><span class="tree"> <span class="dim">├──</span></span> <span class="dim">transfer</span> physical copy<span class="hv-wide">, promote by staged rename</span></span><span class="hv-l hv-l6"><span class="tree"> <span class="dim">└──</span></span> <span class="dim">discovery</span> automatic</span></div>
<span class="hv-l hv-l1"><span class="cmd">sqb plan</span></span><span class="hv-l hv-l2"><span class="strong">Migrations</span> <span class="dim">(1)</span></span><span class="hv-l hv-l3"><span class="tree"><span class="dim">└──</span></span> daily_revenue <span class="info strong">migrate</span><span class="hv-wide"> <span class="dim">prod.revenue -&gt;</span> prod.daily_revenue</span></span><span class="hv-l hv-l4"><span class="tree"> <span class="dim">├──</span></span> <span class="dim">compatibility</span> <span class="ok">compatible</span></span><span class="hv-l hv-l5"><span class="tree"> <span class="dim">├──</span></span> <span class="dim">transfer</span> physical copy<span class="hv-wide">, promote by staged rename</span></span><span class="hv-l hv-l6"><span class="tree"> <span class="dim">└──</span></span> <span class="dim">old name</span> prod.revenue</span><span class="hv-l hv-l7"><span class="tree"> <span class="dim">├──</span></span> <span class="dim">view</span> until 2026-11-05</span><span class="hv-l hv-l8"><span class="tree"> <span class="dim">└──</span></span> <span class="dim">old table</span> archived</span></div>
</div>

<section>
Expand Down Expand Up @@ -190,7 +190,7 @@ <h3>Turn review comments into compile errors</h3>
<h3>Reorganise without breaking anything</h3>
<p>

Declarations live next to the models that use them, and the compiler enforces who can see them. <code>sqb scope</code> shows what a move would break.
Declarations live next to the models that use them, and the compiler enforces who can see them. <code>sqb scope</code> shows what a move would break, and <code>sqb mv</code> moves the model's private macros, enums and constants with it.
</p>
</div>
<pre class="terminal"><span class="tree">models/marts/
Expand Down Expand Up @@ -322,15 +322,24 @@ <h3>See what the tests missed</h3>
<h3>Rename models without rebuilding history</h3>
<p>

A renamed incremental model keeps its table instead of starting again. If the logic changed too, declare <code>migrate_from</code>.
<code>sqb rename</code> and <code>sqb mv</code> update every reference and keep the existing table, so an incremental model doesn't start again. The old name keeps working as a view. Renamed columns keep their history too.
</p>
</div>
<pre class="terminal"><span class="cmd">sqb plan</span>
<pre class="terminal"><span class="cmd">sqb rename model:daily_activity_rollup daily_order_rollup</span>
<span class="info strong">Rename model daily_activity_rollup -&gt; daily_order_rollup</span>
<span class="dim">├──</span> models/marts/daily_order_rollup.sql<span class="dim"> (moved from models/marts/daily_activity_rollup.sql)</span>
<span class="dim">└──</span> models/marts/hourly_activity_with_daily_context.sql
<span class="dim"> └──</span> 36:19 reference __ref(&quot;daily_activity_rollup&quot;) -&gt; __ref(&quot;daily_order_rollup&quot;)
<span class="ok strong">Compiled: ok, 2 files changed</span>

<span class="cmd">sqb plan</span>
<span class="strong">Migrations</span> <span class="dim">(1)</span>
<span class="dim">└──</span> daily_order_rollup <span class="info strong">migrate</span> <span class="dim">dev.daily_activity_rollup -&gt;</span> dev.daily_order_rollup
<span class="dim">├── compatibility</span> <span class="ok">compatible</span>
<span class="dim">├── transfer</span> physical copy, promote by staged rename
<span class="dim">└── discovery</span> automatic</pre>
<span class="dim">└── old name</span> dev.daily_activity_rollup
<span class="dim">├── view</span> until 2026-11-05
<span class="dim">└── old table</span> archived</pre>
</div>
<div class="step">
<div class="step-text">
Expand Down
71 changes: 69 additions & 2 deletions website/public/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -742,7 +742,7 @@ footer a {
margin-top: 0;
}

/* Hero visual: a model is moved and renamed, then sqb plan shows the migration. */
/* Hero visual: sqb mv moves and renames a model, then sqb plan shows the migration. */
.hero {
display: grid;
grid-template-columns: minmax(0, 1fr) auto;
Expand All @@ -754,7 +754,7 @@ footer a {
border: 1px solid var(--panel-border);
border-left: 1px solid var(--inner-line);
border-radius: var(--radius);
min-height: 236px;
min-height: 300px;
}

.hero-visual {
Expand Down Expand Up @@ -823,6 +823,27 @@ footer a {
}
}

@keyframes hv-l0 {
0%,
6% {
opacity: 0;
transform: translateY(3px);
}
9%,
92% {
opacity: 1;
transform: none;
}
96%,
100% {
opacity: 0;
}
}

.hv-l0 {
animation-name: hv-l0;
}

@keyframes hv-l1 {
0%,
24% {
Expand Down Expand Up @@ -949,6 +970,48 @@ footer a {
animation-name: hv-l6;
}

@keyframes hv-l7 {
0%,
45% {
opacity: 0;
transform: translateY(3px);
}
48%,
92% {
opacity: 1;
transform: none;
}
96%,
100% {
opacity: 0;
}
}

.hv-l7 {
animation-name: hv-l7;
}

@keyframes hv-l8 {
0%,
48% {
opacity: 0;
transform: translateY(3px);
}
51%,
92% {
opacity: 1;
transform: none;
}
96%,
100% {
opacity: 0;
}
}

.hv-l8 {
animation-name: hv-l8;
}

@media (prefers-reduced-motion: reduce) {
.hero-visual .hv-a,
.hero-visual .hv-b,
Expand Down Expand Up @@ -979,4 +1042,8 @@ footer a {
.hero-visual .hv-wide {
display: none;
}

.hero-visual .hv-break::after {
content: '\\\A ';
}
}
2 changes: 1 addition & 1 deletion website/recordings/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ scripts are the source; the rendered GIF, MP4 and PNG files go to `out/`, which

| Demo | Shows |
|------|-------|
| `rename` | A model is moved and renamed, and `sqb plan` migrates the existing table. |
| `rename` | `sqb mv` moves and renames a model, and `sqb plan` migrates the existing table. |
| `contract` | A renamed column fails `sqb compile` against an enforced contract. |
| `rules` | A custom rule and a missing test mock fail `sqb compile`. |
| `scope` | `sqb scope --as-path` previews what a move would lose. |
Expand Down
3 changes: 2 additions & 1 deletion website/recordings/prepare.sh
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,12 @@ rm -rf "$dir"
mkdir -p "$here/scratch"
case "$demo" in
rename)
# Build the model under its old name, so the tape can move it back to models/finance.
# Build the model under its old name, so the tape can move it back to models/finance with sqb mv.
cp -r "$examples/hero-shop" "$dir"
cd "$dir"
mkdir -p models/marts
mv models/finance/daily_revenue.sql models/marts/revenue.sql
rmdir models/finance
sqb build >/dev/null ;;
contract)
# Give daily_revenue an enforced contract, then rename one of its columns in the SELECT.
Expand Down
7 changes: 4 additions & 3 deletions website/recordings/tapes/rename.tape
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
Source tapes/common.tape
Set Height 800
Set Height 1080
Output out/rename.gif
Output out/rename.mp4
Hide
Expand All @@ -10,10 +10,11 @@ Show
Type "tree --noreport models"
Enter
Sleep 1500ms
Type "mv models/marts/revenue.sql models/finance/daily_revenue.sql"
Type "sqb mv model:revenue models/finance/daily_revenue.sql"
Sleep 300ms
Enter
Sleep 800ms
Wait@60s /\$\s*$/
Sleep 1500ms
Type "sqb plan"
Sleep 300ms
Enter
Expand Down
Loading