Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Prisma @updatedAt doesn't change on update

So I've been working on a NestJS backend using postgresql and prisma, what I've noticed during testing, is that when I update one of the records using the .update() function from prisma, it doesn't actually update the updatedAt field; this is the example of one of my prisma models:

model Channel {
    id           String    @id @default(uuid())
    name         String?
    description  String?
    type         String    @default("DIRECT")
    password     String?
    firstOwnerId String?
    ownerId      String?
    adminIds     String[]  @default([])
    mutes        Mute[]
    kicks        Kick[]
    users        User[]
    messages     Message[]

    createdAt DateTime @default(now())
    updatedAt DateTime @updatedAt

    @@map("channels")
}

this is how I can the updating function:

    await this.prismaService.channel.update({
        where: {
          id: channelId,
        },
        data: {
          users: {
            connect: {
              id: userId,
            },
          },
        },
        include: channelIncludes,
      });

I am using the latest version of Prisma and NestJS "@prisma/client": "^5.1.1" and "@nestjs/common": "^10.2.2"

I gave the SQL migration generated by Prisma a look, and I noticed that the updatedAt doesn't really have something that will get it updated on change;

CREATE TABLE "channels" (
    "id" TEXT NOT NULL,
    "name" TEXT,
    "description" TEXT,
    "type" TEXT NOT NULL DEFAULT 'DIRECT',
    "password" TEXT,
    "firstOwnerId" TEXT,
    "ownerId" TEXT,
    "adminIds" TEXT[] DEFAULT ARRAY[]::TEXT[],
    "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
    "updatedAt" TIMESTAMP(3) NOT NULL,

    CONSTRAINT "channels_pkey" PRIMARY KEY ("id")
);

I believe it should have something like; DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP

like image 718
Abdel Avatar asked Oct 24 '25 05:10

Abdel


1 Answers

Prisma updates the @updatedAt field in the underlying engine. The Channel model has either a One-to-Many relationship with the foreign key on the Users table (where I assume you have a channelId field) or an implicit Many-to-Many relation where prisma manages the relation table itself.

In both cases, prisma is not writing to the channels table and therefore doesn't touch update the 'updatedAt' field on channels. It's either updating the channelId foreign key on the users table or the internal _ChannelsToUsers table prisma creates.

A proposed workaround would be to tell prisma to update updatedAt during the query. (Note that if you have a Many-to-Many relationship this won't update the users table.)

    await this.prismaService.channel.update({
        where: {
          id: channelId,
        },
        data: {
>>>       updatedAt: new Date(),
          users: {
            connect: {
              id: userId,
            },
          },
        },
        include: channelIncludes,
      });

If you have a Many-to-Many you will need to either update the user in the query by adding update: { where: { id: userId }, data: { updatedAt: new Date() }} to the user part of the query args if prisma handles it properly or a second write, potentially as part of a transaction.

like image 168
masterwaffle Avatar answered Oct 26 '25 18:10

masterwaffle