question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Migrate creates unnecessary migrations

See original GitHub issue

Bug description

Running prisma migrate keeps dropping and re adding the same foreign key constraints over and over.

How to reproduce

Repro: https://github.com/f0rr0/prisma-migrate-bug-repro

Given the schema

generator client {
  provider = "prisma-client-js"
}

datasource db {
  provider = "postgresql"
  url      = "postgresql://prisma:prisma@127.0.0.1:5432/database"
}

model User {
  /// The value of this field is generated by the database as: `gen_random_uuid()`.
  id            String          @id @default(dbgenerated())
  UserStoryLike UserStoryLike[]

  @@map(name: "users")
}

model UserStoryLike {
  storyId String
  userId  String
  Story   Story  @relation(fields: [storyId], references: [id])
  User    User   @relation(fields: [userId], references: [id])

  @@id([storyId, userId])
  @@map(name: "user-story-likes")
}

model Story {
  /// The value of this field is generated by the database as: `gen_random_uuid()`.
  id            String          @id @default(dbgenerated())
  UserStoryLike UserStoryLike[]

  @@map(name: "stories")
}

Running prisma migrate dev --create-only --preview-feature gives the following migration file.

-- CreateTable
CREATE TABLE "users" (
    "id" TEXT NOT NULL,

    PRIMARY KEY ("id")
);

-- CreateTable
CREATE TABLE "user-story-likes" (
    "storyId" TEXT NOT NULL,
    "userId" TEXT NOT NULL,

    PRIMARY KEY ("storyId","userId")
);

-- CreateTable
CREATE TABLE "stories" (
    "id" TEXT NOT NULL,

    PRIMARY KEY ("id")
);

-- AddForeignKey
ALTER TABLE "user-story-likes" ADD FOREIGN KEY("storyId")REFERENCES "stories"("id") ON DELETE CASCADE ON UPDATE CASCADE;

-- AddForeignKey
ALTER TABLE "user-story-likes" ADD FOREIGN KEY("userId")REFERENCES "users"("id") ON DELETE CASCADE ON UPDATE CASCADE;

After editing the above to following

CREATE EXTENSION IF NOT EXISTS pgcrypto;

-- CreateTable
CREATE TABLE "users" (
    "id" UUID NOT NULL DEFAULT gen_random_uuid(),

    PRIMARY KEY ("id")
);

-- CreateTable
CREATE TABLE "user-story-likes" (
    "storyId" UUID NOT NULL,
    "userId" UUID NOT NULL,

    PRIMARY KEY ("storyId","userId")
);

-- CreateTable
CREATE TABLE "stories" (
    "id" UUID NOT NULL DEFAULT gen_random_uuid(),

    PRIMARY KEY ("id")
);

-- AddForeignKey
ALTER TABLE "user-story-likes" ADD FOREIGN KEY("storyId")REFERENCES "stories"("id") ON DELETE CASCADE ON UPDATE CASCADE;

-- AddForeignKey
ALTER TABLE "user-story-likes" ADD FOREIGN KEY("userId")REFERENCES "users"("id") ON DELETE CASCADE ON UPDATE CASCADE;

and applying through prisma migrate dev --preview-feature succeeds but generates another migration:

-- DropForeignKey
ALTER TABLE "user-story-likes" DROP CONSTRAINT "user-story-likes_storyId_fkey";

-- DropForeignKey
ALTER TABLE "user-story-likes" DROP CONSTRAINT "user-story-likes_userId_fkey";

-- AddForeignKey
ALTER TABLE "user-story-likes" ADD FOREIGN KEY("storyId")REFERENCES "stories"("id") ON DELETE CASCADE ON UPDATE CASCADE;

-- AddForeignKey
ALTER TABLE "user-story-likes" ADD FOREIGN KEY("userId")REFERENCES "users"("id") ON DELETE CASCADE ON UPDATE CASCADE;

All further invocations of migrate include the above migration.

Expected behavior

The unnecessary migration is not created.

Environment & setup

  • OS: Mac OS
  • Database: PostgreSQL
  • Node.js version: 15.5.1
  • Prisma version:
@prisma/cli          : 2.14.0
@prisma/client       : 2.14.0
Current platform     : darwin
Query Engine         : query-engine 5d491261d382a2a5ffdc71de17072b0e409f1cc1 (at node_modules/@prisma/engines/query-engine-darwin)
Migration Engine     : migration-engine-cli 5d491261d382a2a5ffdc71de17072b0e409f1cc1 (at node_modules/@prisma/engines/migration-engine-darwin)
Introspection Engine : introspection-core 5d491261d382a2a5ffdc71de17072b0e409f1cc1 (at node_modules/@prisma/engines/introspection-engine-darwin)
Format Binary        : prisma-fmt 5d491261d382a2a5ffdc71de17072b0e409f1cc1 (at node_modules/@prisma/engines/prisma-fmt-darwin)
Studio               : 0.332.0

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Reactions:2
  • Comments:6 (3 by maintainers)

github_iconTop GitHub Comments

2reactions
pimeyscommented, Feb 4, 2021

Hi @f0rr0,

I tried this with 2.16 and yeah, I can see the drift. But. We’ll be introducing the native types GA very soon, and using that code path I cannot replicate the problem anymore.

So, here’s how you could deal with it before the next version. Set the data model into:

generator client {
  provider = "prisma-client-js"
  previewFeatures = ["nativeTypes"]
}

datasource db {
  provider = "postgresql"
  url      = "postgresql://postgres:prisma@localhost:5432/postgres"
}

model User {
  /// The value of this field is generated by the database as: `gen_random_uuid()`.
  id            String          @id @default(dbgenerated()) @db.Uuid
  UserStoryLike UserStoryLike[]

  @@map(name: "users")
}

model UserStoryLike {
  storyId String @db.Uuid
  userId  String @db.Uuid
  Story   Story  @relation(fields: [storyId], references: [id])
  User    User   @relation(fields: [userId], references: [id])

  @@id([storyId, userId])
  @@map(name: "user-story-likes")
}

model Story {
  /// The value of this field is generated by the database as: `gen_random_uuid()`.
  id            String          @id @default(dbgenerated()) @db.Uuid
  UserStoryLike UserStoryLike[]

  @@map(name: "stories")
}

This will then generate only one migration file:

-- CreateTable
CREATE TABLE "users" (
    "id" UUID NOT NULL,

    PRIMARY KEY ("id")
);

-- CreateTable
CREATE TABLE "user-story-likes" (
    "storyId" UUID NOT NULL,
    "userId" UUID NOT NULL,

    PRIMARY KEY ("storyId","userId")
);

-- CreateTable
CREATE TABLE "stories" (
    "id" UUID NOT NULL,

    PRIMARY KEY ("id")
);

-- AddForeignKey
ALTER TABLE "user-story-likes" ADD FOREIGN KEY ("storyId") REFERENCES "stories"("id") ON DELETE CASCADE ON UPDATE CASCADE;

-- AddForeignKey
ALTER TABLE "user-story-likes" ADD FOREIGN KEY ("userId") REFERENCES "users"("id") ON DELETE CASCADE ON UPDATE CASCADE;

The next version of Prisma (2.17) will most probably allow you to remove the preview feature from the generator block. Hope this helps you to move forward, please open a new issue if the native types version still generates drift when it shouldn’t.

1reaction
codeslayer1commented, Feb 2, 2021

Any updates on the above issue @janpio ? I am now facing this issue after upgrading to v2.16. Prisma Migrate is dropping all my existing constraints and recreating them.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Overcome Common Migration Pitfalls - Create a Web ...
Sometimes we can make a mistake when creating a migration. Don't worry! ... First, let's create our unwanted migration.
Read more >
Does Django create useless migrations? - Stack Overflow
Django indeed sometimes creates "useless" migrations. That is because certain backends might do something at the database level (like altering ...
Read more >
makemigrations unable to generate necessary migration for ...
If a user has an existing model state that uses model inheritance and changes a superclass to become abstract then makemigrations is unable...
Read more >
“Migrations zero” or how to handle migrations on a large ...
Working with Django is paired with working with migrations. Migrations are operations needed to be run on a database so that its state...
Read more >
Managing Migrations - EF Core - Microsoft Learn
The migration scaffolding process warns when an operation might result in data loss (like dropping a column). If you see that warning, be ......
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found