Início / RLS / Erro PGRST200: Could not find a relationship · Read in English
Supabase · Correção de erro
Erro PGRST200: Could not find a relationship in the schema cache
Juntar tabelas dentro do select() (embedding) só funciona por uma chave estrangeira. Sem chave estrangeira entre as duas tabelas, não há relação. Crie a chave estrangeira (a coluna referenciada precisa ser chave primária ou única), recarregue o cache e, se houver duas chaves entre as mesmas tabelas, diga qual você quer.
01 O que o erro diz
resposta
{
"code": "PGRST200",
"message": "Could not find a relationship between 'books' and 'authors' in the schema cache",
"details": "Searched for a foreign key relationship between 'books' and 'authors' in the schema 'public', but no matches were found."
}
Uma query como supabase.from('books').select('title, authors(name)') pede pra Data API juntar as tabelas por uma chave estrangeira. Ela não adivinha o join pelo nome da coluna: só ter author_id não basta.
02 Veja quais chaves estrangeiras existem
check.sql
select conrelid::regclass as from_table, confrelid::regclass as to_table, conname from pg_constraint where contype = 'f' and connamespace = 'public'::regnamespace order by 1;
03 Crie a chave estrangeira
migration.sql
alter table public.books add constraint books_author_id_fkey foreign key (author_id) references public.authors(id); notify pgrst, 'reload schema';
A coluna referenciada precisa ser chave primária ou única, senão o Postgres recusa a constraint (there is no unique constraint matching given keys).
04 Duas chaves entre as mesmas tabelas: PGRST201
Se books tem author_id e editor_id apontando pra authors, o join fica ambíguo e você recebe PGRST201, cuja dica lista as opções. Diga o nome da chave estrangeira:
// escolha a relação pelo nome da constraint supabase.from('books').select('title, author:authors!books_author_id_fkey(name)')
05 Achou a relação, mas as linhas vêm vazias
Aí é RLS, não a relação: a tabela do join tem as próprias policies, e linhas que quem chama não pode ver voltam como null ou lista vazia. Confira a policy de SELECT da tabela do join.
Seu app está vazando agora?
Cole a URL do seu app no ar. O scanner lê a página e o JavaScript atrás de uma chave service_role do Supabase, o vazamento que passa por cima de todas as policies deste guia.
Pegue isso antes de ir pro ar
airlock-rls é um gate de CI que quebra o build quando uma tabela vai pro ar exposta ou uma policy é permissiva: o mesmo tipo de bug, pego no CI contra um banco com as suas migrations aplicadas, antes de chegar em produção.
Ou comece pelo nextjs-supabase-starter: auth + uma tabela com RLS + um teste de isolamento, pra começar de um padrão que já vem selado.
Baixe o cheat sheet de RLS do Supabase
As regras de ouro, as armadilhas que vazam em produção, policies corretas e o teste de isolamento, numa página só (em inglês).
FAQ
Dá pra juntar tabelas de schemas diferentes?
A chave estrangeira pode apontar pra outro schema, mas as duas tabelas precisam estar em schemas expostos pela Data API pro join funcionar.
Criei a chave estrangeira e continua dando PGRST200.
Recarregue o cache do schema (notify pgrst, 'reload schema') e confira os nomes das tabelas no select: o join usa nome de tabela (ou o apelido que você der), não nome de coluna.