When LakeQL writes records to a table, two independent choices decide what happens. Get them straight up front and the rest of this section reads easily:
- Where and how the data is written is the write strategy . It goes into object storage as files (Parquet), or straight into a table via SQL.
- How the write combines with data already there is the load strategy . It replaces everything, appends, or both.
The two axes are orthogonal. You pick one write strategy per data source and a load strategy per write. Any combination is valid. append works the same whether the bytes land as Parquet files or as INSERT INTO rows.
Choosing a write strategy #
You configure this once, on the data source's writeConfig.
| Strategy | Use it when | What it does |
|---|---|---|
| External storage (default) | You back your tables with object storage (a data lake — S3/MinIO/GCS/Azure) and register them through an external table catalog. | Serializes records to a file format, uploads the files, and registers them via table DDL. Needs a files-sdk instance, a serializer, and a basePath. |
| INSERT INTO | You want rows written directly into an existing engine table, with no object storage. | Writes rows through batched INSERT INTO SQL. Supports batching, optional table creation, and a staging-and-swap for full loads. |
For the Trino adapter, the storage strategy is the default. Opt into the SQL path with writeConfig: { strategy: "insert" }. See Trino write config for both writeConfig shapes side by side.
Choosing a load strategy #
This is passed per write (and, for generated endpoints, baked into the endpoint's mutation block). It is the same set of options regardless of the preceding write strategy.
| Strategy | Result |
|---|---|
append | Adds the new records, keeps what's already there. |
full_load | Replaces the whole dataset with the new records. |
full_load_append | Replaces the "latest" dataset and extends a growing "all" history. |
How they fit together #
A single write is one cell in the grid of (write strategy × load strategy). Take two examples. A Trino storage write with append serializes the records to Parquet, uploads them under the configured basePath, and registers them without touching existing files. A Trino INSERT write with full_load stages rows in a pending table and swaps it into place. Same load semantics, different mechanics underneath.
The rest of this section goes one layer deeper:
- Write strategies — what each write strategy does step by step and the capability matrix of which adapter supports which.
- Load strategies — the precise behavior of each, including the edge cases (empty input, errors).
- Partitioning — how the storage strategy lays files out on disk.