Prisma: Updates on relation field IDs causing issues with subsequent fetching

Created on 16 Mar 2020  路  1Comment  路  Source: prisma/prisma

Most helpful comment

Different message from the internal discussion with clearer explanation:

There's one big caveat with the current relation-as-IDs implementation: Take the following model and query:

// Relation inlining must happen on ModelA
model ModelA {
    b B @id
}
model ModelB {
    id String @default(cuid()) @id
    a A?
}
mutation {
    updateOneA(
        where: { b: 1 },
        data: {
            b: { connect: { id: 2 } }
        }
    ) {
        b { id }
    }
}



md5-62cfad48622ae0c941d872490a80720b



```graphql
mutation {
    updateOneA(
        where: { b: 1, c: 1, d: 1, other: "test" },
        data: {
            b: { connect: { id: 5 } }
            c: { update: { id: 10 } }
            d: { upsert: {
                where:  { id: 1 }
                create: { id: 15 }
                update: { id: 20 }
            }}
        }
    ) {
        b { id } // -> Expect 5
        c { id } // -> Expect 10
        d { id } // -> Expect either 15 or 20
    }
}

Why? Nested queries are run in sequence, the first nested query executes but the second will cause a rollback because the ID changed at best... there are also worst-case scenarios you can construct with this where you're updating a record that is not supposed to be updated with subsequent nested queries.

Tl;dr: Updating inline relations that are part of the primary ID of a model fails in unexpected ways, but does the correct writes under the hood in simple cases. Be extremely careful what you do.

>All comments

Different message from the internal discussion with clearer explanation:

There's one big caveat with the current relation-as-IDs implementation: Take the following model and query:

// Relation inlining must happen on ModelA
model ModelA {
    b B @id
}
model ModelB {
    id String @default(cuid()) @id
    a A?
}
mutation {
    updateOneA(
        where: { b: 1 },
        data: {
            b: { connect: { id: 2 } }
        }
    ) {
        b { id }
    }
}



md5-62cfad48622ae0c941d872490a80720b



```graphql
mutation {
    updateOneA(
        where: { b: 1, c: 1, d: 1, other: "test" },
        data: {
            b: { connect: { id: 5 } }
            c: { update: { id: 10 } }
            d: { upsert: {
                where:  { id: 1 }
                create: { id: 15 }
                update: { id: 20 }
            }}
        }
    ) {
        b { id } // -> Expect 5
        c { id } // -> Expect 10
        d { id } // -> Expect either 15 or 20
    }
}

Why? Nested queries are run in sequence, the first nested query executes but the second will cause a rollback because the ID changed at best... there are also worst-case scenarios you can construct with this where you're updating a record that is not supposed to be updated with subsequent nested queries.

Tl;dr: Updating inline relations that are part of the primary ID of a model fails in unexpected ways, but does the correct writes under the hood in simple cases. Be extremely careful what you do.

Was this page helpful?
0 / 5 - 0 ratings