'<project_slug>.<dataset_slug>'. Two ways to use it:
- a statement is run and forgotten: from the library, over HTTP, or from an agent’s
querytool; - a query is kept on the platform and versioned, and, wired to a SQL transform, produces a dataset with its place in the lineage.
Statements
SELECT. It may JOIN several datasets, as long as they belong to the same organization. A tabular dataset is read as its table; a file dataset is read as the Parquet files it holds, so a file dataset of CSVs answers 403 Cannot query this dataset.
Formats
Arrow is the efficient one for anything wide or long: JSON repeats every column name on every row.
Limits and timeouts
Without aLIMIT of its own, a result is capped at 1000 rows unless limit= says otherwise. The cut is reported: truncated and limit in the JSON body, X-Gwenlake-Truncated and X-Gwenlake-Row-Limit as headers whatever the format. A client reading a whole table should page with LIMIT/OFFSET, which is what the transforms layer does.
timeout= overrides the client’s default for this call. A scan over a large dataset can take far longer to answer than an ordinary request: the engine reads every file behind it before the first byte comes back.
Read a result whole, export it
A statement without aLIMIT is capped at 1000 rows. To read a result whole, the library pages it, wrapping your statement in LIMIT/OFFSET pages until one comes back short, and gives it back as Arrow, as a DataFrame, or written to a file whose format follows its extension:
to_file streams page by page, so a result larger than memory is fine; it returns the rows written. A statement with its own LIMIT is read in one page, as is. The same from the terminal:
-o is the short form of --out, and -o - writes to stdout, which lets a result travel through a pipe or ssh. Give --format then, since there is no extension to read it from; only the data goes to stdout, the row count goes to stderr. In Python, to_file takes an open binary stream the same way, with format=.
Branches and snapshots
Two optional suffixes on a handle:
The snapshot forms exist for incremental transforms, which compose them from what a build pins; nothing in an ordinary statement needs them. A snapshot suffix on a file dataset is a
400, and so is one with no append-only history between its two ends.
Over HTTP
Stored queries
A query is a SQL text stored on the platform and versioned: every save keeps the previous text, and a branch may carry its own copy. Wired to a SQL transform, it produces a dataset, with its inputs derived from theFROM and JOIN references of the text.
Three ways to get one: write it in the SQL editor of the Atlas interface, POST /sql/queries with the text, or commit a .sql file in a repository the platform scans, with the dataset it produces in a header comment.
From a repository
orders_by_day.sql
sales.orders_by_day from sales.orders; a later commit re-versions the text. The file’s @input headers are informative: the inputs are derived from the references in the SQL itself.
Over the API
?branch= on the reads and the PATCH addresses a data branch: a branch save creates the branch’s copy and leaves the trunk’s text alone; a build on that branch runs the branch’s text.
Wiring it to a dataset
A SQL transform names the query and the output; the inputs come from the text.400 naming the reference:
- every
FROM/JOINreference is a dataset of the same project; - no
:branchand no@snapshotsuffix: a SQL transform reads its inputs whole, on the branch of the build; - the output is a tabular dataset where the organization supports them, and is produced by this transform alone (
409for a second producer).
Input of a transform, or let the workflow rebuild it whenever its inputs change.
Statements (client.statements.create) are the library’s SQL surface.
These endpoints are served by the platform and used by the Atlas interface; they are being opened on the public gateway progressively, and the Python library does not wrap them yet. The API reference lists what the gateway exposes today.