Dart SDK - Data#

The builder mirrors PostgREST-style DX.

Read#

// Select all
await db.from('profiles').select(null).execute();

// Select columns
await db.from('profiles').select('id, nationality').execute();

// Single row by primary key
await db.from('profiles').get(recordId);

// First matching row, or null
await db.from('profiles').eq('nationality', 'Kenya').single();

// Row count only (no rows transferred)
final count = await db.from('profiles').head(); // data: {'count': 42}
DART

select takes a nullable column list; select(null) projects all columns.

Filters#

MethodSQL
.eq(col, v)col = v
.neq(col, v)col != v
.gt(col, v) / .gte(col, v)col > v / col >= v
.lt(col, v) / .lte(col, v)col < v / col <= v
.like(col, '%x%')LIKE
.ilike(col, '%x%')ILIKE (case-insensitive)
.isNull(col) / .isNotNull(col)IS NULL / IS NOT NULL
.inList(col, ['a','b'])IN (...)

Filters chain with AND.

Ordering and pagination#

await db.from('profiles').order('created_at', ascending: false).execute();
await db.from('profiles').limit(50).offset(100).execute();
DART

For large tables use keyset pagination (O(1) per page vs O(n) for offset):

var page = await db.from('logs').select('id').order('id').limit(100).execute();
while (page.data!.isNotEmpty) {
  final lastId = '${page.data!.last['id']}';
  // process page...
  page = await db
      .from('logs')
      .select('id')
      .order('id')
      .limit(100)
      .cursor(lastId)
      .execute();
}
DART

Joins#

Column-picker joins - no SQL needed:

final rows = await db
    .from('messages')
    .select('id, message, users.full_name as sender')
    .join(JoinSpec(
      table: 'users',
      fromColumn: 'user_id',
      toColumn: 'id',
      type: 'LEFT JOIN', // INNER JOIN | LEFT JOIN | RIGHT JOIN | FULL JOIN
    ))
    .limit(20)
    .execute();
DART
  • JoinSpec(table:, fromColumn:, toColumn:, type:) builds the ON clause
  • on: raw ON clause (advanced; takes precedence over the column pair)
  • Joined columns are keyed as {table}.{column} (or your alias)
  • Joins route through POST /projects/{id}/query/run

Write#

// Insert single or many (server fills id/created_at)
await db.from('profiles').insert({'full_name': 'Asha Mwinyi', 'nationality': 'Tanzania'});
await db.from('profiles').insert([
  {'full_name': 'Asha'},
  {'full_name': 'Juma'},
]);

// Update (requires an eq('id', ...) filter first)
await db.from('profiles').eq('id', recordId).update({'nationality': 'Kenya'});

// Delete (requires an eq('id', ...) filter first)
await db.from('profiles').eq('id', recordId).delete();
DART

update() / delete() throw a StateError unless an eq('id', ...) filter is set first.

Raw request#

await db.request<Map<String, dynamic>>(
  '/projects/${db.client.projectId}/data/profiles',
  method: 'GET',
);
DART

Next: Auth.