Skip to content

Bulk upsert fails on conflict #1138

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
aarjan opened this issue Mar 24, 2025 · 1 comment
Open

Bulk upsert fails on conflict #1138

aarjan opened this issue Mar 24, 2025 · 1 comment
Labels
bug Something isn't working postgrest This issue or pull request is related to postgrest

Comments

@aarjan
Copy link

aarjan commented Mar 24, 2025

Describe the bug
I am adding two separate records while creating a chat room for both users.
I get this error when running this query in supabase in flutter app. Key (room_id, from_user_id)=(-, -) already exists. duplicate key value violates unique constraint "unique_room_id_from_user_id"

Here is the db schema

postgres=> \d room;
                                         Table "public.room"
     Column      |           Type           | Collation | Nullable |             Default              
-----------------+--------------------------+-----------+----------+----------------------------------
 id              | bigint                   |           | not null | generated by default as identity
 room_id         | text                     |           |          | 
 user_ids        | character varying[]      |           |          | 
 created_at      | timestamp with time zone |           |          | now()
 updated_at      | timestamp with time zone |           |          | now()
 unmatch         | boolean                  |           |          | false
 from_user_id    | uuid                     |           |          | 
 to_user_id      | uuid                     |           |          | 
 initiated       | boolean                  |           | not null | false
 unmatched_by    | uuid                     |           |          | 
 message_request | boolean                  |           | not null | false
Indexes:
    "room_pkey" PRIMARY KEY, btree (id)
    "unique_room_id_from_user_id" UNIQUE CONSTRAINT, btree (room_id, from_user_id)
final room = RoomModel(
      id: roomID,
      initiated: !isMessageRequest,
      toUserId: user.id,
      fromUserId: fromUserID,
      userIDs: [fromUserID, user.id],
    );

    await _client.from(DBConfig.room).upsert(
      [
        room.toMap(),
        // create room for other user
        room
            .copyWith(
              fromUserId: user.id,
              toUserId: fromUserID,
              isMessageRequest: isMessageRequest,
            )
            .toMap(),
      ],
      onConflict: 'room_id,from_user_id',
    );

Expected behavior
But, It works if i use upsert for these two values separately.

    await _client.from(DBConfig.room).upsert(
          room.toMap(),
          onConflict: 'room_id,from_user_id',
        );

    // create room for other user
    await _client.from(DBConfig.room).upsert(
          room
              .copyWith(
                fromUserId: user.id,
                toUserId: fromUserID,
                isMessageRequest: isMessageRequest,
              )
              .toMap(),
          onConflict: 'room_id,from_user_id',
        );

Version (please complete the following information):
On Linux/macOS

├── supabase_flutter 2.8.4
│   ├── supabase 2.6.3
│   │   ├── functions_client 2.4.1
│   │   ├── gotrue 2.11.1
│   │   ├── postgrest 2.4.1
│   │   ├── realtime_client 2.4.2
│   │   ├── storage_client 2.3.1
@aarjan aarjan added the bug Something isn't working label Mar 24, 2025
@Vinzent03
Copy link
Collaborator

I don't quite get the reason of your upserts. Your id column is the primary key, which doesn't change between your both rows you are trying to upsert. Therefore, you can have only one row with that room id. So when you do two separate upserts, I think the first one is just useless, because you overwrite the same row with the new values from your copied room object.
So it makes sense that this one doesn't throw any errors. Your first version, where you upsert both room objects in one go, is probably just how postgresql works. I highly doubt there is any issue with supabase.

@dshukertjr dshukertjr added the postgrest This issue or pull request is related to postgrest label Apr 11, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working postgrest This issue or pull request is related to postgrest
Projects
None yet
Development

No branches or pull requests

3 participants