Fetch data
Read rows from a table. Accepts a column list, count mode, and HEAD-only mode.
Build a SELECT. Pass any number of column expressions (default *) and chain filters / modifiers before calling .execute. The builder also exposes result-shape switchers (single, maybe_single, csv, explain).
Signature
supabase.from(table).select(*columns, count: nil, head: nil)columns is a splat — pass each column expression as a separate string, or pass none to default to "*". Embedded resources ("posts(*)", "author:users!author_id(name)") are supported by PostgREST and pass through unchanged.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
columns | String (splat) | Optional | One or more column expressions. Whitespace inside quoted strings is preserved; whitespace outside is stripped. Defaults to "*". |
count | String | Optional | One of "exact", "planned", "estimated". Adds Prefer: count=... so APIResponse#count is populated from the Content-Range header. |
head | Boolean | Optional | When true, issues a HEAD request — no body, count only. Pair with count: to read a row total without fetching rows. |
Returns
A chainable builder. Call .execute to fire the request and receive an APIResponse (data: and count:). Use .single, .maybe_single, .csv, or .explain to change the response shape before executing.
Example — fetch every column
response = supabase.from("countries").select("*").execute
response.data # => [{ "id" => 1, "name" => "Algeria", "continent" => "Africa" }, ...]Example — pick specific columns + filters + ordering
response = supabase
.from("countries")
.select("id, name")
.eq("continent", "Africa")
.order("name")
.limit(20)
.execute
response.data # => [{ "id" => 1, "name" => "Algeria" }, ...]Example — count rows alongside the data
response = supabase
.from("countries")
.select("*", count: "exact")
.eq("continent", "Africa")
.execute
response.data # => [...rows...]
response.count # => 54Example — count only, no rows (HEAD)
response = supabase
.from("countries")
.select("*", count: "exact", head: true)
.eq("continent", "Africa")
.execute
response.data # => []
response.count # => 54Example — embedded resources
PostgREST resource embedding works as a column expression. The shape mirrors what PostgREST returns, so authors picking columns inside the embedded resource use the standard relation(col1, col2) syntax.
response = supabase
.from("posts")
.select("id, title, author:users!author_id(id, full_name)")
.order("id", desc: true)
.limit(10)
.executeExample — fetch exactly one row
.single flips the Accept header so PostgREST returns the row as an object (not an array of length 1) and raises Supabase::Postgrest::Errors::APIError if the result is 0 or more than 1 row.
response = supabase
.from("countries")
.select("*")
.eq("id", 1)
.single
.execute
response.data # => { "id" => 1, "name" => "Algeria", ... }