Skip to content

Querying an uploaded file via DuckDB

Saiku Cloud’s Starter tier supports a file-upload data path. You upload a parquet or CSV; Saiku stores it in R2; the engine queries it via in-process DuckDB. No customer warehouse needed; no firewall to set up.

This is the simplest “I want to see Saiku query something” path for evaluators and small workloads.

Tier impact: [Starter] — file-upload is the Starter-tier data path. [Team] + [Business] customers usually have their own warehouse so they hit one of the other connection docs instead, though file-upload works on every tier.

Driver: Saiku Cloud ships DuckDB’s official JDBC driver. Files are queried in-process — no network round-trip on the data path.

What you’ll need

  • A parquet, CSV, or JSON file ≤ 5 GB.
  • An idea of which columns are dimensions vs which are measures (we’ll auto-infer if you let us).

Step 1 — Upload the file

  1. Sign in at https://cloud.saiku.bi/.

  2. Navigate to Files in the left sidebar.

  3. Drag-and-drop your file into the upload area, or click Upload file and pick it from your filesystem.

While the upload progresses, Saiku Cloud:

  1. Streams the file to our R2 bucket (an S3-compatible store).
  2. Spins up an in-process DuckDB session against the file.
  3. Runs DESCRIBE to read column types.
  4. Returns the schema to the dashboard for review.

For parquet and JSON, schema inference is exact (the file format carries column types). For CSV we sniff the first 10,000 rows and guess — usually correct, but you can override types in the next step if something comes out wrong.

Step 2 — Review the proposed schema

After upload, Saiku navigates you to a schema-review screen. The columns are listed with inferred types:

  • INTEGER / BIGINT / DOUBLE → numeric. Default proposal: a Sum measure.
  • VARCHAR / TEXT → categorical. Default proposal: a dimension.
  • TIMESTAMP / DATE → time. Default proposal: a time-hierarchy dimension with year/month/day levels.

You can:

  • Drop columns you don’t need (cuts cube load time).
  • Change a numeric column from Sum to Avg / Count / Min / Max.
  • Promote a string column to a dimension hierarchy if it has natural levels (region → country → city).
  • Add a calculated measure (Mondrian MDX expression — for power users).

Or accept the defaults and click Propose schema. Most casual evaluators do exactly this.

Step 3 — Open the cube

After save, Saiku navigates you to Analyze. Your uploaded file is now a queryable cube. Drag dimensions onto rows/columns, drag measures into values, see the result.

Refreshing the data

Re-uploading the same file (same name) replaces it. Saiku re-runs schema inference + flags any column-type changes. If the new file has columns that don’t match the existing schema (you renamed a column, added a new one), you’ll be prompted to either:

  • Re-propose — generate a fresh schema. Loses any per-column tweaks you made.
  • Keep + reconcile — preserves your tweaks; drops references to columns that no longer exist.

File-format gotchas

CSV: type inference

CSV doesn’t carry column types. Saiku Cloud sniffs the first 10,000 rows and guesses. Common surprises:

  • A column that’s mostly integers but has the occasional "NA" or "-" gets inferred as VARCHAR. Either clean the source data, or override the column to INTEGER (Saiku will treat non-numeric values as NULL).
  • Dates in non-ISO format (12/31/2025 instead of 2025-12-31) get inferred as VARCHAR. Cleaner to convert to ISO in your source pipeline; Saiku doesn’t auto-detect locale-specific date formats.

Parquet: prefer this format

Parquet carries column types + statistics natively. Schema inference is exact, file size is typically 1/4 of the CSV equivalent, and DuckDB can skip entire row-groups when filtering. Use parquet if you have a choice.

JSON: nested fields

JSON-lines (one object per line) is supported. Deeply nested structures (objects-inside-arrays-inside-objects) are flattened to dotted column names — customer.address.city becomes a column customer.address.city. If your nesting is very deep, the column-count balloons; flatten in your source pipeline if you have one.

Size + retention

What you DON’T get with this flow

  • Multi-file joins — each upload is its own cube. To join two files, do it in your source pipeline before upload, or use the cube-library + a multi-file Mondrian schema (advanced).
  • Live data — uploads are point-in-time snapshots. For live data, connect a warehouse via the BYOC flows instead.
  • Custom partitioning — DuckDB queries the whole file. Cubes over 1 GB feel sluggish on first query (subsequent queries are cached). For larger workloads, consider MotherDuck instead — see Connecting MotherDuck.

Try with FoodMart

Want to test Saiku Cloud with this dialect before connecting your own data? Download the FoodMart sample dataset packaged for DuckDB:

FoodMart sample dataset for DuckDB