Consulta de datos

Aprenda a consultar y filtrar datos de su base de datos.

Nota: Este es contenido de ejemplo/marcador de posición con fines de demostración.

Consulte y filtre datos de forma eficiente con el constructor de consultas de Supabase.

Consultas básicas

Seleccionar todo

const { data, error } = await client
  .from('projects')
  .select('*');

Seleccionar columnas específicas

const { data, error } = await client
  .from('projects')
  .select('id, name, created_at');

Seleccionar con datos relacionados

const { data, error } = await client
  .from('projects')
  .select(`
    id,
    name,
    account:accounts(id, name),
    tasks(id, title, completed)
  `);

Filtrado

Igual

const { data } = await client
  .from('projects')
  .select('*')
  .eq('status', 'active');

Distinto

const { data } = await client
  .from('projects')
  .select('*')
  .neq('status', 'deleted');

Mayor que / Menor que

const { data } = await client
  .from('projects')
  .select('*')
  .gt('created_at', '2024-01-01')
  .lt('budget', 10000);

En un array

const { data } = await client
  .from('projects')
  .select('*')
  .in('status', ['active', 'pending']);

Like (coincidencia de patrones)

const { data } = await client
  .from('projects')
  .select('*')
  .like('name', '%website%');

Búsqueda de texto completo

const { data } = await client
  .from('projects')
  .select('*')
  .textSearch('description', 'design & development');

Ordenación

Ordenar por

const { data } = await client
  .from('projects')
  .select('*')
  .order('created_at', { ascending: false });

Ordenar por varios campos

const { data } = await client
  .from('projects')
  .select('*')
  .order('status')
  .order('created_at', { ascending: false });

Paginación

Límite

const { data } = await client
  .from('projects')
  .select('*')
  .limit(10);

Rango (desplazamiento)

const page = 2;
const pageSize = 10;
const from = (page - 1) * pageSize;
const to = from + pageSize - 1;

const { data, count } = await client
  .from('projects')
  .select('*', { count: 'exact' })
  .range(from, to);

Agregaciones

Recuento

const { count } = await client
  .from('projects')
  .select('*', { count: 'exact', head: true });

Recuento con filtros

const { count } = await client
  .from('projects')
  .select('*', { count: 'exact', head: true })
  .eq('status', 'active');

Consultas avanzadas

Varios filtros

const { data } = await client
  .from('projects')
  .select('*')
  .eq('account_id', accountId)
  .eq('status', 'active')
  .gte('created_at', startDate)
  .lte('created_at', endDate)
  .order('created_at', { ascending: false })
  .limit(20);

Condiciones OR

const { data } = await client
  .from('projects')
  .select('*')
  .or('status.eq.active,status.eq.pending');

OR anidado

const { data } = await client
  .from('projects')
  .select('*')
  .or('and(status.eq.active,priority.eq.high),status.eq.urgent');

Joins

Inner join

const { data } = await client
  .from('projects')
  .select(`
    *,
    account:accounts!inner(
      id,
      name
    )
  `)
  .eq('account.name', 'Acme Corp');

Left join

const { data } = await client
  .from('projects')
  .select(`
    *,
    tasks(*)
  `);

Gestión de valores nulos

Es nulo

const { data } = await client
  .from('projects')
  .select('*')
  .is('completed_at', null);

No es nulo

const { data} = await client
  .from('projects')
  .select('*')
  .not('completed_at', 'is', null);

Insertar datos

Inserción individual

const { data, error } = await client
  .from('projects')
  .insert({
    name: 'New Project',
    account_id: accountId,
    status: 'active',
  })
  .select()
  .single();

Inserción múltiple

const { data, error } = await client
  .from('projects')
  .insert([
    { name: 'Project 1', account_id: accountId },
    { name: 'Project 2', account_id: accountId },
  ])
  .select();

Actualizar datos

Actualizar con filtro

const { data, error } = await client
  .from('projects')
  .update({ status: 'completed' })
  .eq('id', projectId)
  .select()
  .single();

Actualizar varias filas

const { data, error } = await client
  .from('projects')
  .update({ status: 'archived' })
  .eq('account_id', accountId)
  .lt('updated_at', oldDate);

Eliminar datos

Eliminar con filtro

const { error } = await client
  .from('projects')
  .delete()
  .eq('id', projectId);

Eliminación múltiple

const { error } = await client
  .from('projects')
  .delete()
  .in('id', projectIds);

Upsert

Insertar o actualizar

const { data, error } = await client
  .from('projects')
  .upsert({
    id: projectId,
    name: 'Updated Name',
    status: 'active',
  })
  .select()
  .single();

RPC (procedimientos almacenados)

Llamar a una función de base de datos

const { data, error } = await client
  .rpc('get_user_projects', {
    user_id: userId,
  });

Con parámetros complejos

const { data, error } = await client
  .rpc('search_projects', {
    search_term: 'design',
    account_ids: [1, 2, 3],
    min_budget: 5000,
  });

Gestión de errores

Gestión básica de errores

const { data, error } = await client
  .from('projects')
  .select('*');

if (error) {
  console.error('Error fetching projects:', error.message);
  throw error;
}

return data;

Gestión de errores tipada

import { PostgrestError } from '@supabase/supabase-js';

function handleDatabaseError(error: PostgrestError) {
  switch (error.code) {
    case '23505': // unique_violation
      throw new Error('A project with this name already exists');
    case '23503': // foreign_key_violation
      throw new Error('Invalid account reference');
    default:
      throw new Error('Database error: ' + error.message);
  }
}

Tipos de TypeScript

Tipos generados

import { Database } from '~/types/database.types';

type Project = Database['public']['Tables']['projects']['Row'];
type ProjectInsert = Database['public']['Tables']['projects']['Insert'];
type ProjectUpdate = Database['public']['Tables']['projects']['Update'];

Consultas tipadas

const { data } = await client
  .from('projects')
  .select('*')
  .returns<Project[]>();

Consejos de rendimiento

  1. Seleccione solo las columnas necesarias - No use select('*') innecesariamente
  2. Use índices - Cree índices en las columnas que se filtran con frecuencia
  3. Limite los resultados - Pagine siempre los conjuntos de datos grandes
  4. Evite las consultas N+1 - Use joins en lugar de varias consultas
  5. Use RPC para consultas complejas - Traslade la lógica a la base de datos
  6. Use caché cuando sea posible - Use React Query o una herramienta similar
  7. Analice las consultas - Use EXPLAIN ANALYZE en SQL

Buenas prácticas

  1. Gestione siempre los errores - Compruebe las respuestas de error
  2. Valide la entrada - Use Zod o una herramienta similar
  3. Use TypeScript - Genere y utilice tipos
  4. Nomenclatura coherente - Siga las convenciones de nomenclatura de la base de datos
  5. Documente las consultas complejas - Añada comentarios
  6. Pruebe las consultas - Escriba pruebas unitarias para las operaciones de base de datos
  7. Supervise el rendimiento - Haga un seguimiento de las consultas lentas