Brendonovich / prisma-client-rust

Type-safe database access for Rust
https://prisma.brendonovich.dev
Apache License 2.0
1.8k stars 104 forks source link

Is there an equivalent to `connectOrCreate`? #234

Closed lostfictions closed 1 year ago

lostfictions commented 1 year ago

Hi there, thanks a lot for making this library! I've been testing out transitioning an Electron project that used Prisma over to Tauri, and being able to keep my workflow and reuse my schema has been a huge boon.

I've encountered one hitch so far. Previously I was doing something like this:

async function updateThing(input: Thing) {
  const { id, tags, ...fields } = input;

  await db.thing.update({
    where: { id },
    data: {
      ...fields,
      tags: {
        // first, remove all existing tags:
        set: [],
        // now, for each provided tag, either connect it if it exists, or create it if it doesn't.
        connectOrCreate: tags.map((tag) => ({
          where: { tag },
          create: { tag },
        })),
      },
    },
  });

  // finally, clean up any unreferenced tags:
  await db.$queryRaw<[{ count: number }]>`
    DELETE FROM Tag WHERE
      (SELECT count(1) FROM _ThingToTag WHERE B = Tag.id) = 0;
  `;
}

with a schema that looked something like this:

model Thing {
  id    Int      @id @default(autoincrement())
  // ...other stuff...
  tags  Tag[]
}

model Tag {
  id     Int    @id @default(autoincrement())
  tag    String @unique
  things Thing[]
}

Is something like this possible with prisma-client-rust at the moment?

Brendonovich commented 1 year ago

Not currently, that falls under #44 since it requires possibly creating a nested record. For now I'd recommend using _batch to execute a bunch of upserts in a transaction, which would each either create a record and connect it, or connect an existing record.

lostfictions commented 1 year ago

Makes sense! Thanks a lot for the quick reply.