Search code examples
postgresqlrelational-databasesupabasesupabase-database

"Uncaught Error: More than one relationship was found" with Supabase client query


I'm building a multitenant app and running into an error after adding multiple relations that point to the same table:

Uncaught Error: More than one relationship was found for teams and users

When performing this query:

const data = await supabaseClient.from('organizations')
.select(`
  *,
  teams(
    id,
    org_id,
    name,
    members:users(
      id,
      full_name,
      avatar_url
    )
  )
`);

I have the following table structures (leaving off some fields for brevity):

table users (
  id uuid PK
  full_name text
  email text
)

table organizations (
  id uuid PK
  ....
)

table organization_memberships (
  id uuid PK
  organization_id uuid FK
  user_id uuid FK
  role ENUM
)

table teams (
  id uuid PK
  name text PK
)

table team_memberships (
    id uuid PK
    team_id uuid FK
    user_id uuid FK
    role ENUM
)

table team_boards (
  id uuid PK
  team_id uuid FK
  owner_id uuid FK
)

Under the hood, Supabase uses PostREST for queries. And I have deciphered from the error message that the query is ambigious and it's unsure which relationship(s) to fulfill. I'm not sure how to tell Supabase which relation to use in this particular query to avoid this error.

Here's the more verbose console error from postREST:

{
  hint: "By following the 'details' key, disambiguate the request by changing the url to /origin?select=relationship(*) or /origin?select=target!relationship(*)",
  message: 'More than one relationship was found for teams and users',
  details: [
    {
      origin: 'public.teams',
      relationship: 'public.team_memberships[team_memberships_team_id_fkey][team_memberships_user_id_fkey]',
      cardinality: 'm2m',
      target: 'public.users'
    },
    {
      origin: 'public.teams',
      relationship: 'public.team_boards[team_boards_team_id_fkey][team_boards_owner_id_fkey]',
      cardinality: 'm2m',
      target: 'public.users'
    }
  ]
}

Solution

  • Digging a bit deeper into the PostgREST docs, it turns out what I was looking for is the disambiguation operator, !.

    The working query looks like this (note that we are disambiguating which relation to use to satisfy the members query):

    const data = await supabaseClient.from('organizations')
    .select(`
      *,
      teams(
        id,
        org_id,
        name,
        members:users!team_memberships(
          id,
          full_name,
          avatar_url
        )
      )
    `);