Skip to content

Migrate into DuckDB

Tested with: DuckDB 1.5 on Databasezy · zb CLI 0.1

Sources: A .duckdb database file, a CSV file, or another Databasezy DuckDB instance.

DuckDB instances are served by Databasezy’s DuckDB HTTP server, so the copy is SQL over POST /query on both sides. An uploaded .duckdb file is opened read-only by the same server inside the migration Job; a CSV file is loaded into a staging database first (read_csv, header row, types detected).

  1. schemas and sequences (restarted after the source’s last value);
  2. tables from DuckDB’s catalog as CREATE TABLE IF NOT EXISTS, in an order the foreign keys accept;
  3. rows paged from the source in rowid order and rendered as typed literals ('<value>'::<type>), which DuckDB casts back exactly, nested STRUCT/LIST/MAP values included; inserted in batches under the server’s 1 MiB request limit;
  4. indexes, then views.
shell
# --dry-run prints the preflight checklist and the exact plan without changing anything
zb migrate --from ./analytics.duckdb --engine duckdb --to inst_abc
zb migrate --from ./events.csv --engine duckdb --include events --to inst_abc
zb migrate --from inst_src --to inst_abc

Follow it with zb migrate status <mig_id>, or in the portal under the instance’s Migrate in tab.

count(*) per table and a hash of every table’s columns and types. Mismatches are listed in the result; nothing is switched for you.

  • The file must be written by the instance’s DuckDB version or an older one; re-export newer files with EXPORT DATABASE / IMPORT DATABASE.
  • Parquet uploads are not read by the engine image; load the file into a .duckdb database (CREATE TABLE t AS FROM 'file.parquet') and upload that.
  • Macros, user-defined types (other than inline ENUMs), secrets and attached databases are not copied.

How migrations work covers preflight, verification and cutover; engine conversions covers moves between engines.