Search code examples
mysqlnode.jscrudprisma

Copying database record with it's relations in prisma


My system works on Node.JS with Prisma connected to mysql.

Let's say I have two tables in my database: house [ID|house_name] and resident [ID|name|house_ID]. One house can be referenced by many residents (one-to-many relation). I want to copy one house with it's residents (creating a new record for each resident). I'm taking data from the house, including it's residents, then posting new house. Now I want to post all residents but with their house reference ID changed. The easiest way to do it would be, I think, to iterate through each resident that reference copied house and change their house_ID to... what exactly? How do I get ID of a new house when it's auto increment on database side? I can't find the correct record of a house using name as it's not unique. Also I can't depend on taking last record as there can be writes to the DB between write and read.

Example code:

const prisma = require("../prisma");

exports.copyHouse = async (req, res) => {

    let house = await prisma.House.findUnique({
        where: {
            id: +req.body.houseId
        },
        include: {
            residents: true,
        }
    });

    let newHouseData = {
        name: req.body.name,
    };

    residents = house.residents;

    await prisma.House.create({
        data: newHouseData
    });

    if (residents !== null) {
        for (let i = 0; i < residents.length; i++) {

            residents[i].houseId = //what to put here????

            await prisma.Resident.create({
                data: residents[i]
            });
        }
    }

    res.status(200).json({ messages: [
        {
            message: 'House copied successfully',
            type: 'success'
        }
    ]});
};

What would be the smartest way to approach this problem?


Solution

  • After some research I've managed to solve my problem - method await prisma.House.create return a record from a database. So I can just assign it to a variable and read id from there. So it would be

        let newHouseDb = await prisma.House.create({
            data: newHouseData
        });
    
        if (residents !== null) {
            for (let i = 0; i < residents.length; i++) {
    
                residents[i].houseId = newHouseDb.id;
    
                await prisma.Resident.create({
                    data: residents[i]
                });
            }
        }