prisma / migrate

Issues for Prisma Migrate are now tracked at prisma/prisma. This repo was used to track issues for Prisma Migrate Experimental and is now deprecated.
https://www.prisma.io/docs/concepts/components/prisma-migrate
Apache License 2.0
767 stars 22 forks source link

Named relation in schema breaks "lift up" #213

Closed olup closed 4 years ago

olup commented 4 years ago

I have this schema

generator photon {
  provider = "photonjs"
}

datasource db {
  provider = "sqlite"
  url      = "file:dev.db"
}

model User {
  id     String  @default(cuid()) @id @unique
  email  String  @unique
  name   String?
  roles  Role[]
  drafts Page[]  @relation(name: "draftOwner")
}

model Role {
  slug      String  @default(cuid()) @id @unique
  users     User[]
  locked    Boolean @default(false)
  viewPages Page[]  @relation(name: "users_can_view_pages")
  editPages Page[]  @relation(name: "users_can_edit_pages")
}

model Page {
  id         String  @default(cuid()) @id @unique
  title      String
  slug       String  @unique
  content    String?
  published  Boolean
  draftOwner User?   @relation(name: "draftOwner")

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

  canView Role[] @relation(name: "users_can_view_pages")
  canEdit Role[] @relation(name: "users_can_edit_pages")

  parents  Page[] @relation("Parents")
  children Page[] @relation("Parents")
}

I can save and up a first migration. However any following edits are throwing an error on prisma2 lift up. Specifically :

Response: {
  "jsonrpc": "2.0",
  "error": {
    "code": 4466,
    "message": "An error happened. Check the data field for details.",
    "data": {
      "type": "DataModelErrors",
      "code": 1001,
      "errors": [
        "Argument \"name\" is already specified.",
        "Argument \"name\" is already specified.",
        "Argument \"name\" is already specified.",
        "Argument \"name\" is already specified.",
        "Argument \"name\" is already specified.",
        "Argument \"name\" is already specified."
      ]
    }
  },
  "id": 2
}
An error happened. Check the data field for details.

I do not have the problem if I use the blog example's schema.

olup commented 4 years ago

I investigated a bit more. Adding elements to the schema bit by bit and migrating on and on I can say that the relation @relation(name: "draftOwner") is causing the problem (other reelations may too, but I did't check them). Meaning that I can migrate with this relation, then cannot lift up any subsequent changes in the schema. Unamed relation doesn't seem to trigger this problem.

olup commented 4 years ago

After a bit more tests, the named relation @relation("Parents") in my Page model doesn't trigger any error. However, @relation(name: "users_can_view_pages") breaks lift as well, so it seems that the problem originates in named relations linking two models, be it a 1:M or M:M relation.

pantharshit00 commented 4 years ago

I was successfully able to migrate the datamodel you have provided with prisma2@2.0.0-preview016.2, binary version: b72fd0a786adc77ba6c61d0a9637ff0371e433b0

image

Can you please try again with the latest version and with a new database? There were a few breaking changes in lift in the past couple of weeks which might have affected your database.

olup commented 4 years ago

@pantharshit00 can you confirm you are able to migrate a change once this schema has been migrated in the first place ? I mean: migrate the schema , edit the schema (add whattever) migrate the change ( second migration) this is what breaks for me

(I tested the bug on new db files (sqlite) with prisma 2 16.2 on Ubuntu latest. I tested it a 100th time to find the faulty line in the schema nd I tried with and without elements in the db. Btw, someone was having the same bug and posted on slack a few hours after I did)

momakes3 commented 4 years ago

This happens for me too.

smartnet-club commented 4 years ago

+1 (second lift up with error "Argument \"name\" is already specified.")

model Site { id Int @id name String inAccessPoint AccessPoint[] @relation(name: "ToSite") outAccessPoint AccessPoint[] @relation(name: "FromSite") }

model AccessPoint { id Int @id name String fromSite Site @relation(name: "FromSite") toSite Site @relation(name: "ToSite") }

After first lift save & lift up there are no relation tables in database.

If run lift save one more time (without changing schema), lift generates steps:

{
  "stepType": "CreateDirectiveArgument",
  "model": "Site",
  "field": "inAccessPoint",
  "directive": "relation",
  "argument": "name",
  "value": "\"ToSite\""
},
{
  "stepType": "DeleteDirectiveArgument",
  "model": "Site",
  "field": "inAccessPoint",
  "directive": "relation",
  "argument": ""
},
{
  "stepType": "CreateDirectiveArgument",
  "model": "Site",
  "field": "outAccessPoint",
  "directive": "relation",
  "argument": "name",
  "value": "\"FromSite\""
},
{
  "stepType": "DeleteDirectiveArgument",
  "model": "Site",
  "field": "outAccessPoint",
  "directive": "relation",
  "argument": ""
},
{
  "stepType": "CreateDirectiveArgument",
  "model": "AccessPoint",
  "field": "fromSite",
  "directive": "relation",
  "argument": "name",
  "value": "\"FromSite\""
},
{
  "stepType": "DeleteDirectiveArgument",
  "model": "AccessPoint",
  "field": "fromSite",
  "directive": "relation",
  "argument": ""
},
{
  "stepType": "CreateDirectiveArgument",
  "model": "AccessPoint",
  "field": "toSite",
  "directive": "relation",
  "argument": "name",
  "value": "\"ToSite\""
},
{
  "stepType": "DeleteDirectiveArgument",
  "model": "AccessPoint",
  "field": "toSite",
  "directive": "relation",
  "argument": ""
},

And following lift up with error "Argument \"name\" is already specified."

mysql

prisma2@2.0.0-preview016.2: version "2.0.0-preview016.2" resolved "https://registry.yarnpkg.com/prisma2/-/prisma2-2.0.0-preview016.2.tgz#36f3e9cf8f1e44215df4ab9347033b32563d21d0" integrity sha512-K/xnzfpuAiISUGAkqEAvVXRfMe6DyJWTT0Nk8xaTspc3ymm3nU35PR49DeqX839WMTb5tXLnzyi3hgi+074Jwg==

pantharshit00 commented 4 years ago

I can reproduce this now, thanks for detailed reproduction @smartnet-club

pantharshit00 commented 4 years ago

I think it is a bug in our diffing logic cc @tomhoule

tomhoule commented 4 years ago

Can confirm it's probably that. I'll take this.

smartnet-club commented 4 years ago

The problem persists in 2.0.0-preview017.2 Second lift up on the same db scheme generates steps Create - Delete:

{ "version": "0.3.14-fixed", "steps": [ { "stepType": "CreateDirectiveArgument", "model": "Subject", "field": "groups", "directive": "relation", "argument": "references", "value": "[id]" }, { "stepType": "CreateDirectiveArgument", "model": "Subject", "field": "groups", "directive": "relation", "argument": "name", "value": "\"SubjectGroup\"" }, { "stepType": "CreateDirectiveArgument", "model": "Subject", "field": "groups", "directive": "relation", "argument": "onDelete", "value": "NONE" }, { "stepType": "DeleteDirectiveArgument", "model": "Subject", "field": "groups", "directive": "relation", "argument": "" }, { "stepType": "CreateDirectiveArgument", "model": "Subject", "field": "messages", "directive": "relation", "argument": "references", "value": "[id]" }, { "stepType": "CreateDirectiveArgument", "model": "Subject", "field": "messages", "directive": "relation", "argument": "name", "value": "\"SubjectMessage\"" }, { "stepType": "CreateDirectiveArgument", "model": "Subject", "field": "messages", "directive": "relation", "argument": "onDelete", "value": "NONE" }, { "stepType": "DeleteDirectiveArgument", "model": "Subject", "field": "messages", "directive": "relation", "argument": "" }, { "stepType": "CreateDirectiveArgument", "model": "Subject", "field": "account", "directive": "relation", "argument": "references", "value": "[id]" }, { "stepType": "CreateDirectiveArgument", "model": "Subject", "field": "account", "directive": "relation", "argument": "name", "value": "\"SubjectAccount\"" }, { "stepType": "CreateDirectiveArgument", "model": "Subject", "field": "account", "directive": "relation", "argument": "onDelete", "value": "NONE" }, { "stepType": "DeleteDirectiveArgument", "model": "Subject", "field": "account", "directive": "relation", "argument": "" }, { "stepType": "CreateDirectiveArgument", "model": "Group", "field": "subjects", "directive": "relation", "argument": "references", "value": "[id]" }, { "stepType": "CreateDirectiveArgument", "model": "Group", "field": "subjects", "directive": "relation", "argument": "name", "value": "\"SubjectGroup\"" }, { "stepType": "CreateDirectiveArgument", "model": "Group", "field": "subjects", "directive": "relation", "argument": "onDelete", "value": "NONE" }, { "stepType": "DeleteDirectiveArgument", "model": "Group", "field": "subjects", "directive": "relation", "argument": "" }, { "stepType": "CreateDirectiveArgument", "model": "Group", "field": "policies", "directive": "relation", "argument": "references", "value": "[id]" }, { "stepType": "CreateDirectiveArgument", "model": "Group", "field": "policies", "directive": "relation", "argument": "name", "value": "\"GroupPolicy\"" }, { "stepType": "CreateDirectiveArgument", "model": "Group", "field": "policies", "directive": "relation", "argument": "onDelete", "value": "NONE" }, { "stepType": "DeleteDirectiveArgument", "model": "Group", "field": "policies", "directive": "relation", "argument": "" }, { "stepType": "CreateDirectiveArgument", "model": "Group", "field": "parent", "directive": "relation", "argument": "references", "value": "[id]" }, { "stepType": "CreateDirectiveArgument", "model": "Group", "field": "parent", "directive": "relation", "argument": "name", "value": "\"GroupTree\"" }, { "stepType": "CreateDirectiveArgument", "model": "Group", "field": "parent", "directive": "relation", "argument": "onDelete", "value": "NONE" }, { "stepType": "DeleteDirectiveArgument", "model": "Group", "field": "parent", "directive": "relation", "argument": "" }, { "stepType": "CreateDirectiveArgument", "model": "Group", "field": "children", "directive": "relation", "argument": "references", "value": "[id]" }, { "stepType": "CreateDirectiveArgument", "model": "Group", "field": "children", "directive": "relation", "argument": "name", "value": "\"GroupTree\"" }, { "stepType": "CreateDirectiveArgument", "model": "Group", "field": "children", "directive": "relation", "argument": "onDelete", "value": "NONE" }, { "stepType": "DeleteDirectiveArgument", "model": "Group", "field": "children", "directive": "relation", "argument": "" }, { "stepType": "CreateDirectiveArgument", "model": "Group", "field": "escorts", "directive": "relation", "argument": "references", "value": "[id]" }, { "stepType": "CreateDirectiveArgument", "model": "Group", "field": "escorts", "directive": "relation", "argument": "name", "value": "\"GroupEscort\"" }, { "stepType": "CreateDirectiveArgument", "model": "Group", "field": "escorts", "directive": "relation", "argument": "onDelete", "value": "NONE" }, { "stepType": "DeleteDirectiveArgument", "model": "Group", "field": "escorts", "directive": "relation", "argument": "" }, { "stepType": "CreateDirectiveArgument", "model": "Message", "field": "author", "directive": "relation", "argument": "references", "value": "[id]" }, { "stepType": "CreateDirectiveArgument", "model": "Message", "field": "author", "directive": "relation", "argument": "name", "value": "\"SubjectMessage\"" }, { "stepType": "CreateDirectiveArgument", "model": "Message", "field": "author", "directive": "relation", "argument": "onDelete", "value": "NONE" }, { "stepType": "DeleteDirectiveArgument", "model": "Message", "field": "author", "directive": "relation", "argument": "" }, { "stepType": "CreateDirectiveArgument", "model": "Message", "field": "comments", "directive": "relation", "argument": "references", "value": "[id]" }, { "stepType": "CreateDirectiveArgument", "model": "Message", "field": "comments", "directive": "relation", "argument": "name", "value": "\"MessageComment\"" }, { "stepType": "DeleteDirectiveArgument", "model": "Message", "field": "comments", "directive": "relation", "argument": "" }, { "stepType": "CreateDirectiveArgument", "model": "Message", "field": "parent", "directive": "relation", "argument": "references", "value": "[id]" }, { "stepType": "CreateDirectiveArgument", "model": "Message", "field": "parent", "directive": "relation", "argument": "name", "value": "\"MessageComment\"" }, { "stepType": "DeleteDirectiveArgument", "model": "Message", "field": "parent", "directive": "relation", "argument": "" } ] }

greben99 commented 4 years ago

I can also confirm it is still an issue in 2.0.0-preview017.2.

tomhoule commented 4 years ago

I reproduced the issue in preview 16 and 17, and I can also confirm this is fixed in the latest alpha and in preview18 (that will be released today). The fix was in https://github.com/prisma/prisma-engine/pull/206

Please open a new issue if you still encounter problems using lift :)