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.

Introspection is changing field casing

See original GitHub issue

I think naming rules can be improved significantly, as many people already mentioned above.

I encountered this problem today while migrating to the newest version (2.14.0 at the moment) of prisma migrate. Earlier in my project, I’ve created a database with legacy prisma migrate cli.

So, for example, I have the types Employee and Degree with many-to-many relation. And I have all names in camelCase in those types. In the old version, prisma migrate has created a reference table called _DegreeToEmployee. So, when I ran the new introspection - it renamed the existing field on Degree like so:

- employees Employee[] @relation(references: [id])
+ Employee Employee[]

New introspection certainly needs to properly address these kinda cases in the future. Main suggestions:

  • when migrating from older versions of prisma - preserve original field names for all kinds of relations (1-1, 1-many, many-many);
  • casing should be inferred or set manually, via command parameter, for example.

P.S.: Btw, I didn’t notice it at first and wasted a lot of hours, trying to understand, why my code broke, totally my fault tho. Needless to say, it was quite annoying to manually review generated diff, because my schema is quite large.

_Originally posted by @ivankhm in https://github.com/prisma/prisma/issues/3659#issuecomment-759812738_

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:5 (4 by maintainers)

github_iconTop GitHub Comments

1reaction
ivankhmcommented, Jan 19, 2021

Hi! Sorry for the delay, I didn’t check my email for notifications 😦

I’m not sure, if you need the hole schema, because this problem occurred with only 4 models, but just in case, here it is. My database was first populated with tables back in beta-2 via experimental prisma migrate, if that helps. Right now I’m using prisma@2.14.0. I run npx prisma introspect on my “old” schema:

Schema before introspection

// This is your Prisma schema file,
// learn more about it in the docs: https://pris.ly/d/prisma-schema

datasource mysql {
  provider = "mysql"
  url      = env("DATABASE_URL")
}

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


model BackofficeUser {
  id       Int       @id @default(autoincrement())
  login    String @unique
  password String

  roles    Role[] @relation(references: [id])
}

model Role {
  id                Int       @id @default(autoincrement()) 
  name              String

  accessedEnitities EntityAccess[] @relation(references: [id])
  users             BackofficeUser[] @relation(references: [id])
}

model EntityAccess {
  id             Int       @id @default(autoincrement()) 
  name           String

  allowedActions EntityAction[] @relation(references: [id])
  roles          Role[] @relation(references: [id])
}

model EntityAction {
  id             Int       @id @default(autoincrement())
  type           EntityActionType

  entityAccesses EntityAccess[] @relation(references: [id])
}

model ClientInfo {
  id          Int       @id @default(autoincrement())

  firstName        String
  lastName        String
  middleName        String?

  age         Int

  email       String
  phoneNumber String

  appointment Appointment?
}

model Appointment {
  id         Int       @id @default(autoincrement())
  timeBegin  DateTime
  timeEnd    DateTime
  note       String?

  clientInfo ClientInfo @relation(fields: [clientInfoId], references: [id])
  clientInfoId Int

  schedule   Schedule @relation(fields: [scheduleId], references: [id])
  scheduleId Int
}

model Schedule {
  id                Int       @id @default(autoincrement())
  scheduleDate      DateTime
  timeBegin         DateTime
  timeEnd           DateTime
  intervalMinutes   Int
  
  cabinet           Cabinet? @relation(fields: [cabinetId], references: [id])
  cabinetId         Int?

  employee         Employee @relation(fields: [employeeId], references: [id])
  employeeId       Int
  
  scheduleSpecialty ScheduleSpecialty? @relation(fields: [scheduleSpecialtyId], references: [id])
  scheduleSpecialtyId Int? 
  
  appointments      Appointment[] 
  scheduleTags      ScheduleTag[] @relation(references: [id])
}

model ScheduleSpecialty {
  id        Int       @id @default(autoincrement())
  name      String
  schedules Schedule[] 
}

model Cabinet {
  id             Int       @id @default(autoincrement())
  description    String?
  floor          String
  number         String

  schedules      Schedule[]

  department     Department @relation(fields: [departmentId], references: [id])
  departmentId   Int 

  cabinetSpecials   CabinetSpecial[] @relation(references: [id])
}

model CabinetSpecial {
  id       Int       @id @default(autoincrement())
  name     String
  cabinets Cabinet[] @relation(references: [id])
}

model ScheduleTag {
  id          Int       @id @default(autoincrement())
  htmlContent String?
  inSchedule  Boolean
  name        String?
  schedules   Schedule[] @relation(references: [id])
}

model Employee {
  id                  Int       @id @default(autoincrement())
  firstName           String
  lastName            String
  middleName          String?
  gender              Boolean
  description         String?
  published Boolean @default(true)

  position               Position @relation(fields: [positionId], references: [id])
  positionId Int
  departments         Department[]    @relation(name: "EmployeesInDepartment", references: [id])
  managingDepartments Department[]    @relation(name: "ManagersInDepartment", references: [id])
  tags                EmployeeTag[]  @relation(name: "EmployeeTags", references: [id])
  
  images              Image[]
  schedules      Schedule[]

  
  degrees             Degree[] @relation(references: [id])
  certificates        Certificate[]
  qualifications      Qualification[]
  comments            Comment[]

  educations          Education[] 
}

model Department {
  id          Int       @id @default(autoincrement())
  
  building    String?
  description String?
  floor       String?
  name        String? @unique 
  url         String?

  branchInfo  BranchInfo @relation(fields: [branchInfoId], references: [id])
  branchInfoId Int

  cabinets    Cabinet[]
  comments    Comment[]

  employees   Employee[] @relation(name: "EmployeesInDepartment", references: [id])
  managers    Employee[] @relation(name: "ManagersInDepartment", references: [id])
}

model BranchInfo {
  id           Int       @id @default(autoincrement())
  adress       String
  description  String
  metroStation String?
  name         String
  url          String?

  departments  Department[]
}

model Education {
  id                 Int       @id @default(autoincrement())
  graduationYear     DateTime

  diplomaSpecialty   DiplomaSpecialty @relation(fields: [diplomaSpecialtyId], references: [id])
  diplomaSpecialtyId Int

  institution        Institution @relation(fields: [institutionId], references: [id])
  institutionId      Int

  employee           Employee @relation(fields: [employeeId], references: [id])
  employeeId        Int
}

model DiplomaSpecialty {
  id         Int       @id @default(autoincrement())
  name       String
  educations Education[]
}

model Institution {
  id           Int       @id @default(autoincrement())
  name         String
  certificates Certificate[]
  educations   Education[]
}

model Degree {
  id         Int       @id @default(autoincrement())
  name       String?
  employees Employee[] @relation(references: [id])
}

model Certificate {
  id                   Int       @id @default(autoincrement())
  number               String?
  series               String?
  certificateDate      DateTime

  institution          Institution @relation(fields: [institutionId], references: [id])
  institutionId Int

  certificateSpecialty CertificateSpecialty @relation(fields: [certificateSpecialtyId], references: [id])
  certificateSpecialtyId Int

  employee             Employee @relation(fields: [employeeId], references: [id])
  employeeId     Int
}

model CertificateSpecialty {
  id           Int       @id @default(autoincrement())
  name         String
  certificates Certificate[]
}

model Position {
  id             Int       @id @default(autoincrement())
  name           String
  employees Employee[]
}

model Qualification {
  id                     Int       @id @default(autoincrement())

  employee               Employee @relation(fields: [employeeId], references: [id])
  employeeId Int
  name String? @default("")

  qualificationCategory  QualificationCategory @relation(fields: [qualificationCategoryId], references: [id])
  qualificationCategoryId Int

  qualificationSpecialty QualificationSpecialty @relation(fields: [qualificationSpecialtyId], references: [id])
  qualificationSpecialtyId Int
}

model QualificationCategory {
  id             Int       @id @default(autoincrement())
  name           String
  nameDetail     String?
  qualifications Qualification[]
}

model QualificationSpecialty {
  id             Int       @id @default(autoincrement())
  name           String
  qualifications Qualification[]
}

model Comment {
  id          Int       @id @default(autoincrement())
  rate        Int?
  authorName  String
  authorEmail String

  commentDate DateTime
  commentText String

  published Boolean @default(false)

  department  Department? @relation(fields: [departmentId], references: [id])
  departmentId Int?

  employee    Employee? @relation(fields: [employeeId], references: [id])
  employeeId Int?

  reply       Reply? @relation(fields: [replyId], references: [id])
  replyId Int?
}

model Reply {
  id         Int       @id @default(autoincrement())
  authorName String
  replyText  String
  replyDate  DateTime

  comment    Comment?
}

model EmployeeTag {
  id         Int       @id @default(autoincrement())
  name       String
  employees Employee[] @relation(name: "EmployeeTags", references: [id])
}

model File {
  id       Int       @id @default(autoincrement())
  fileName String
  realPath String

  images   Image[]
}

model Image {
  id       Int       @id @default(autoincrement())
  caption  String?

  employee Employee @relation(fields: [employeeId], references: [id])
  employeeId Int

  file     File @relation(fields: [fileId], references: [id])
  fileId Int
}

enum EntityActionType {
  CREATE
  READ
  UPDATE
  DELETE
}

And here is after npx prisma introspect, the problem is with models Schedule, ScheduleTag, Employee and Degree, witch got field naming changes. It’s strange because other many-to-many relations are perfectly fine.

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

datasource mysql {
  provider = "mysql"
  url      = env("DATABASE_URL")
}

model BackofficeUser {
  id       Int    @id @default(autoincrement())
  login    String @unique
  password String
  roles    Role[]
}

model Role {
  id                Int              @id @default(autoincrement())
  name              String
  users             BackofficeUser[]
  accessedEnitities EntityAccess[]
}

model EntityAccess {
  id             Int            @id @default(autoincrement())
  name           String
  allowedActions EntityAction[]
  roles          Role[]
}

model EntityAction {
  id             Int              @id @default(autoincrement())
  type           EntityActionType
  entityAccesses EntityAccess[]
}

model ClientInfo {
  email       String
  id          Int          @id @default(autoincrement())
  phoneNumber String
  firstName   String
  lastName    String
  middleName  String?
  age         Int
  appointment Appointment?
}

model Appointment {
  clientInfoId Int        @unique
  id           Int        @id @default(autoincrement())
  note         String?
  scheduleId   Int
  timeBegin    DateTime
  timeEnd      DateTime
  clientInfo   ClientInfo @relation(fields: [clientInfoId], references: [id])
  schedule     Schedule   @relation(fields: [scheduleId], references: [id])

  @@index([scheduleId], name: "scheduleId")
}

model Schedule {
  id                  Int                @id @default(autoincrement())
  intervalMinutes     Int
  scheduleDate        DateTime
  scheduleSpecialtyId Int?
  timeBegin           DateTime
  timeEnd             DateTime
  employeeId          Int
  cabinetId           Int?
  cabinet             Cabinet?           @relation(fields: [cabinetId], references: [id])
  employee            Employee           @relation(fields: [employeeId], references: [id])
  scheduleSpecialty   ScheduleSpecialty? @relation(fields: [scheduleSpecialtyId], references: [id])
  appointments        Appointment[]
  ScheduleTag         ScheduleTag[]

  @@index([cabinetId], name: "cabinetId")
  @@index([employeeId], name: "employeeId")
  @@index([scheduleSpecialtyId], name: "scheduleSpecialtyId")
}

model ScheduleSpecialty {
  id        Int        @id @default(autoincrement())
  name      String
  schedules Schedule[]
}

model Cabinet {
  departmentId    Int
  description     String?
  floor           String
  id              Int              @id @default(autoincrement())
  number          String
  department      Department       @relation(fields: [departmentId], references: [id])
  schedules       Schedule[]
  cabinetSpecials CabinetSpecial[]

  @@index([departmentId], name: "departmentId")
}

model CabinetSpecial {
  id       Int       @id @default(autoincrement())
  name     String
  cabinets Cabinet[]
}

model ScheduleTag {
  htmlContent String?
  id          Int        @id @default(autoincrement())
  inSchedule  Boolean
  name        String?
  Schedule    Schedule[]
}

model Employee {
  description         String?
  firstName           String
  gender              Boolean
  id                  Int             @id @default(autoincrement())
  lastName            String
  middleName          String?
  positionId          Int
  published           Boolean         @default(true)
  position            Position        @relation(fields: [positionId], references: [id])
  certificates        Certificate[]
  comments            Comment[]
  educations          Education[]
  images              Image[]
  qualifications      Qualification[]
  schedules           Schedule[]
  Degree              Degree[]
  tags                EmployeeTag[]   @relation("EmployeeTags")
  departments         Department[]    @relation("EmployeesInDepartment")
  managingDepartments Department[]    @relation("ManagersInDepartment")

  @@index([positionId], name: "positionId")
}

model Department {
  branchInfoId Int
  building     String?
  description  String?
  floor        String?
  id           Int        @id @default(autoincrement())
  name         String?    @unique
  url          String?
  branchInfo   BranchInfo @relation(fields: [branchInfoId], references: [id])
  cabinets     Cabinet[]
  comments     Comment[]
  employees    Employee[] @relation("EmployeesInDepartment")
  managers     Employee[] @relation("ManagersInDepartment")

  @@index([branchInfoId], name: "branchInfoId")
}

model BranchInfo {
  adress       String
  description  String
  id           Int          @id @default(autoincrement())
  metroStation String?
  name         String
  url          String?
  departments  Department[]
}

model Education {
  diplomaSpecialtyId Int
  graduationYear     DateTime
  id                 Int              @id @default(autoincrement())
  institutionId      Int
  employeeId         Int
  diplomaSpecialty   DiplomaSpecialty @relation(fields: [diplomaSpecialtyId], references: [id])
  employee           Employee         @relation(fields: [employeeId], references: [id])
  institution        Institution      @relation(fields: [institutionId], references: [id])

  @@index([diplomaSpecialtyId], name: "diplomaSpecialtyId")
  @@index([employeeId], name: "employeeId")
  @@index([institutionId], name: "institutionId")
}

model DiplomaSpecialty {
  id         Int         @id @default(autoincrement())
  name       String
  educations Education[]
}

model Institution {
  id           Int           @id @default(autoincrement())
  name         String
  certificates Certificate[]
  educations   Education[]
}

model Degree {
  id       Int        @id @default(autoincrement())
  name     String?
  Employee Employee[]
}

model Certificate {
  certificateDate        DateTime
  certificateSpecialtyId Int
  employeeId             Int
  id                     Int                  @id @default(autoincrement())
  institutionId          Int
  number                 String?
  series                 String?
  certificateSpecialty   CertificateSpecialty @relation(fields: [certificateSpecialtyId], references: [id])
  employee               Employee             @relation(fields: [employeeId], references: [id])
  institution            Institution          @relation(fields: [institutionId], references: [id])

  @@index([certificateSpecialtyId], name: "certificateSpecialtyId")
  @@index([employeeId], name: "employeeId")
  @@index([institutionId], name: "institutionId")
}

model CertificateSpecialty {
  id           Int           @id @default(autoincrement())
  name         String
  certificates Certificate[]
}

model Position {
  id        Int        @id @default(autoincrement())
  name      String
  employees Employee[]
}

model Qualification {
  employeeId               Int
  id                       Int                    @id @default(autoincrement())
  qualificationCategoryId  Int
  qualificationSpecialtyId Int
  name                     String?                @default("")
  employee                 Employee               @relation(fields: [employeeId], references: [id])
  qualificationCategory    QualificationCategory  @relation(fields: [qualificationCategoryId], references: [id])
  qualificationSpecialty   QualificationSpecialty @relation(fields: [qualificationSpecialtyId], references: [id])

  @@index([employeeId], name: "employeeId")
  @@index([qualificationCategoryId], name: "qualificationCategoryId")
  @@index([qualificationSpecialtyId], name: "qualificationSpecialtyId")
}

model QualificationCategory {
  id             Int             @id @default(autoincrement())
  name           String
  nameDetail     String?
  qualifications Qualification[]
}

model QualificationSpecialty {
  id             Int             @id @default(autoincrement())
  name           String
  qualifications Qualification[]
}

model Comment {
  authorName   String
  commentDate  DateTime
  commentText  String
  departmentId Int?
  employeeId   Int?
  id           Int         @id @default(autoincrement())
  replyId      Int?        @unique
  published    Boolean     @default(false)
  authorEmail  String
  rate         Int?
  department   Department? @relation(fields: [departmentId], references: [id])
  employee     Employee?   @relation(fields: [employeeId], references: [id])
  reply        Reply?      @relation(fields: [replyId], references: [id])

  @@index([departmentId], name: "departmentId")
  @@index([employeeId], name: "employeeId")
}

model Reply {
  authorName String
  id         Int      @id @default(autoincrement())
  replyDate  DateTime
  replyText  String
  comment    Comment?
}

model EmployeeTag {
  id        Int        @id @default(autoincrement())
  name      String
  employees Employee[] @relation("EmployeeTags")
}

model File {
  fileName String
  id       Int     @id @default(autoincrement())
  realPath String
  images   Image[]
}

model Image {
  caption    String?
  employeeId Int
  fileId     Int
  id         Int      @id @default(autoincrement())
  employee   Employee @relation(fields: [employeeId], references: [id])
  file       File     @relation(fields: [fileId], references: [id])

  @@index([employeeId], name: "employeeId")
  @@index([fileId], name: "fileId")
}

enum EntityActionType {
  CREATE
  READ
  UPDATE
  DELETE
}

Just in case, here is an example of tables in actual db:

Screenshots

Снимок экрана 2021-01-19 в 14 07 42 Снимок экрана 2021-01-19 в 14 07 14 Снимок экрана 2021-01-19 в 14 07 00

0reactions
pantharshit00commented, May 16, 2021

I am going to close this as its been 2 months now and there is no activity here.

Please reply if you want us to take another look.

Read more comments on GitHub >

github_iconTop Results From Across the Web

What is introspection? (Reference) - Prisma
In this case, you must manually change the name of one of the two generated User models because duplicate model names are not...
Read more >
Why You Should Disable GraphQL Introspection In Production
Disabling introspection in production is a widely debated topic, but we believe it's one of the first things you can do to harden...
Read more >
Timing of internal processes: Investigating introspection about ...
Here we take a novel approach to this question and build on the previously observed dissociation between the interference of task switching and ......
Read more >
What Is Introspection? Psychology, Definition, And Applications
The concept, in this case, allows people to introduce assumptions about their thoughts, but they may not be completely accurate in doing so....
Read more >
Introspection | Internet Encyclopedia of Philosophy
The case does not show, however, that we can have fallible introspective ... large changes to objects in their visual field, as long...
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