postgresqlgosql-deletesupabase

Unable to delete items using Supabase Go client


I'm developing a REST API with Go and Gin framework that connects to Supabase. I've successfully implemented GET, POST, and PUT operations, but I'm having issues with the DELETE operation.

What I've tried

I've tried various approaches to implement the DeleteItem method:

Approach 1: Using Delete with column and operator

// Approach 1: Using Delete with column and operator
func (s *SupabaseService) DeleteItem(id string) error {
    resp, _, err := s.client.From("items").Delete("id", "eq."+id).Execute()
    if err != nil {
        return err
    }
    // ...
}

This results in error:{"error":"failed to delete item: (21000) DELETE requires a WHERE clause"}

Approach 2: Using Delete without arguments and Filter

// Approach 2: Using Delete without arguments and Filter
func (s *SupabaseService) DeleteItem(id string) error {
    filter := fmt.Sprintf("id=eq.%s", id)
    resp, _, err := s.client.From("items").Delete("", "").Filter(filter, "", "").Execute()
    if err != nil {
        return err
    }
    // ...
}

This fails with compile error: not enough arguments in call to s.client.From(tableName).Delete

Approach 3: Using SingleEq

// Approach 3: Using SingleEq
func (s *SupabaseService) DeleteItem(id string) error {
    resp, _, err := s.client.From("items").Delete().SingleEq("id", id).Execute()
    if err != nil {
        return err
    }
    // ...
}

This fails with: s.client.From(tableName).Delete().SingleEq undefined (type *postgrest.FilterBuilder has no field or method SingleEq)

Environment

Questions

  1. What is the correct way to delete a row from a table using the Supabase Go client?
  2. Is this a limitation in the current supabase-go library?
  3. Are there any workarounds I should consider?

Solution

  • After receiving helpful comments, I managed to solve the issue with deleting items using the Supabase Go client. I'll share the solution for others who might encounter the same problem.

    Working Solution

    Approach 1

    The key insight was using the `Filter` method correctly. Based on the comment from @
    mkopriva, the correct syntax is:

    .Filter("id", "eq", id)  
    
    func (s *SupabaseService) DeleteItem(id string) error {
        tableName := "items"
        
        fmt.Printf("DEBUG SERVICE: Deleting item with ID: %s from table %s\n", id, tableName)
        
        resp, _, err := s.client.From(tableName).Delete("*", "").Filter("id", "eq", id).Execute()
        if err != nil {
            return fmt.Errorf("failed to delete item: %w", err)
        }
    
        fmt.Printf("DEBUG SERVICE: Delete response: %s\n", string(resp))
        
        // Handle empty response (successful deletion)
        if len(resp) == 0 || string(resp) == "" || string(resp) == "[]" {
            fmt.Println("DEBUG SERVICE: Empty response, assuming successful deletion")
            return nil
        }
    
        // Only parse as JSON if response is not empty
        var deleted []interface{}
        if err := json.Unmarshal(resp, &deleted); err != nil {
            return fmt.Errorf("failed to unmarshal delete response: %w (%s)", err, string(resp))
        }
    
        return nil
    }
    

    Approach 2

    Based on the comment from @Sullyvan Nunes

    resp, _, err := s.client.From(tableName).Delete("*", "").Eq("id", id).Execute()
    
    func (s *SupabaseService) DeleteItem(id string) error {
        tableName := "items"
        
        fmt.Printf("DEBUG: Deleting item with ID: %s from table %s\n", id, tableName)
        
        // Using Eq method instead of Filter
        resp, _, err := s.client.From(tableName).Delete("*", "").Eq("id", id).Execute()
        if err != nil {
            return fmt.Errorf("failed to delete item: %w", err)
        }
    
        fmt.Printf("DEBUG: Delete response: %s\n", string(resp))
        
        // Handle empty response (successful deletion)
        if len(resp) == 0 || string(resp) == "" || string(resp) == "[]" {
            fmt.Println("DEBUG: Empty response, assuming successful deletion")
            return nil
        }
    
        // Only parse as JSON if response is not empty
        var deleted []interface{}
        if err := json.Unmarshal(resp, &deleted); err != nil {
            return fmt.Errorf("failed to unmarshal delete response: %w (%s)", err, string(resp))
        }
    
        return nil
    }