I am trying to implement a relation querie with Prisma ORM but this error does not allow.
My system consists in a bugtracker, where the user can report bugs. So I'm linking the User with the bugs. When I try to create a new data this error appears: "Unique constraint failed on the constraint: Bug_authorId_key"
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "mysql"
url = env("DATABASE_URL")
}
model User {
id Int #id #default(autoincrement())
name String
email String #unique
password String
role String #default("User")
bugs Bug[]
teamId Int?
team Team? #relation(fields: [teamId], references: [id])
}
model Team {
id Int #id #default(autoincrement())
name String
users User[]
admins Admin[]
}
model Admin {
id Int #id #default(autoincrement())
name String
email String #unique
password String
role String #default("Admin")
teamId Int?
team Team? #relation(fields: [teamId], references: [id])
}
model Bug {
id Int #id #default(autoincrement())
title String
description String
status String
authorId Int
author User #relation(fields: [authorId], references: [id])
}
const bug = await prisma.bug.create({
data: {
title: req.body.title,
status: req.body.status,
description: req.body.description,
author: {
connect: {id: req.body.authorId}
}
}
})
Related
Looking at the Prisma docs and they show the example below. In this instance, if I'm using MongoDB and define my schema as per below, does Prisma create a collection for me called _CategoryToPost on my behalf to record the many to many relationships?
Or do I have to create my own collection to document this relationship?
model User {
id Int #id #default(autoincrement())
email String #unique
name String?
role Role #default(USER)
posts Post[]
profile Profile?
}
model Profile {
id Int #id #default(autoincrement())
bio String
user User #relation(fields: [userId], references: [id])
userId Int #unique
}
model Post {
id Int #id #default(autoincrement())
createdAt DateTime #default(now())
title String
published Boolean #default(false)
author User #relation(fields: [authorId], references: [id])
authorId Int
categories Category[] #relation(references: [id])
}
model Category {
id Int #id #default(autoincrement())
name String
posts Post[] #relation(references: [id])
}
enum Role {
USER
ADMIN
}
Link to docs
Prisma will create the necessary collections when you run the npx prisma db push command. You should not need to worry about the underlying structure beyond that.
I'm trying to authenticate with email using NextAuth, Prisma and Amazon SES.
I got:
"Server Error - TypeError: email.split(...)[0].trim(...).replaceAll is
not a function."
It comes from the validation process in NextAuth /node_modules/next-auth/core/routes/signin.js (58:40) but I don't know why it occurs.
Amazon SES seems to work fine in the console in sending smtp request.
This is my code (very basic):
import NextAuth from 'next-auth';
import EmailProvider from 'next-auth/providers/email';
import { PrismaAdapter } from '#next-auth/prisma-adapter';
import { PrismaClient } from '#prisma/client';
const prisma = new PrismaClient();
export default NextAuth({
providers: [
EmailProvider({
server: process.env.EMAIL_SERVER,
from: process.env.EMAIL_FROM,
maxAge: 10 * 60,
}),
],
adapter: PrismaAdapter(prisma),
});
In prisma:
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
model Home {
id String #id #default(cuid()) // alternatives: #default(uuid()) or #default(autoincrement())
image String?
title String
description String
price Float
guests Int
beds Int
baths Int
createdAt DateTime #default(now())
updatedAt DateTime #updatedAt
}
model Account {
id String #id #default(cuid())
userId String
type String
provider String
providerAccountId String
refresh_token String? #db.Text
access_token String? #db.Text
expires_at Int?
token_type String?
scope String?
id_token String? #db.Text
session_state String?
user User #relation(fields: [userId], references: [id], onDelete: Cascade)
##unique([provider, providerAccountId])
}
model Session {
id String #id #default(cuid())
sessionToken String #unique
userId String
expires DateTime
user User #relation(fields: [userId], references: [id], onDelete: Cascade)
}
model User {
id String #id #default(cuid())
name String?
email String? #unique
emailVerified DateTime?
image String?
accounts Account[]
sessions Session[]
}
model VerificationToken {
identifier String
token String #unique
expires DateTime
##unique([identifier, token])
}
My models:
model Show {
id Int #id #default(autoincrement())
tvmazeId Int
name String
type Type #relation(fields: [typeId], references: id)
typeId Int
language Language #relation(fields: [languageId], references: id)
languageId Int
genres GenresOnShows[]
status Status #relation(fields: [statusId], references: id)
statusId Int
runtime Int?
premiered DateTime?
ended DateTime?
network Network? #relation(fields: [networkId], references: id)
country Country? #relation(fields: [countryId], references: id)
countryId Int
networkId Int
webchannel Webchannel? #relation(fields: [webchannelId], references: id)
webchannelId Int
tvrageId String? #unique
thetvdbId String? #unique
imdbId String? #unique
imageMed String? #unique
imageOrig String? #unique
summary String
}
model Status {
id Int #id #default(autoincrement())
name String #unique
shows Show[]
}
model Type {
id Int #id #default(autoincrement())
name String #unique
shows Show[]
}
model Language {
id Int #id #default(autoincrement())
name String #unique
shows Show[]
}
model Country {
id Int #id #default(autoincrement())
name String #unique
code String #unique
timezone String
shows Show[]
}
model Network {
id Int #id #default(autoincrement())
name String #unique
shows Show[]
}
model Webchannel {
id Int #id #default(autoincrement())
name String #unique
shows Show[]
}
model Genre {
id Int #id #default(autoincrement())
name String #unique
shows GenresOnShows[]
}
model GenresOnShows {
show Show #relation(fields: [showId], references: [id])
showId Int
genre Genre #relation(fields: [genreId], references: [id])
genreId Int
##id([showId, genreId])
}
What i try is getting show information from an api and populate the database. The problem is, that i need to populate related tables (like network, country, etc.) in the same action.
Here is how i get for example the country:
const country = await prisma.country.upsert(
{
where: {
name: show["network"]["country"]["name"]
},
update: {},
create: {
name: show["network"]["country"]["name"],
code: show["network"]["country"]["code"],
timezone: show["network"]["country"]["timezone"],
}
}
)
and heres the statement i use to try to update the show:
const showInDb = await prisma.show.upsert(
{
where: {
tvmazeId: show["id"]
},
update: {
typeId: {connect: {type}},
languageId: {connect: {language}},
genreConnectOrCreate: genreConnectOrCreate,
statusId: {connect: {status}},
networkId: {connect: {network}},
countryId: {connect: {country}},
webchannelId: {connect: {webchannel}},
name: show["name"],
runtime: parseInt(show["runtime"]),
premiered: new Date(show["premiered"]),
ended: new Date(show["ended"]),
tvrageId: show["externals"]["tvrage"].toString(),
tvdbId: show["externals"]["thetvdb"],
imdbId: show["externals"]["imdb"],
tvmazeId: show["id"],
imageMed: show["image"]["medium"],
imageOrig: show["image"]["original"],
summary: show["summary"]
},
create: {
typeId: {connect: {type}},
languageId: {connect: {language}},
genreConnectOrCreate: genreConnectOrCreate,
statusId: {connect: {status}},
networkId: {connect: {network}},
countryId: {connect: {country}},
webchannelId: webchannel,
name: show["name"],
runtime: parseInt(show["runtime"]),
premiered: new Date(show["premiered"]),
ended: new Date(show["ended"]),
tvmazeId: show["id"],
tvrageId: show["externals"]["tvrage"].toString(),
tvdbId: show["externals"]["thetvdb"],
imdbId: show["externals"]["imdb"],
imageMed: show["image"]["medium"],
imageOrig: show["image"]["original"],
summary: show["summary"]
}
}
)
I tried with the ID (for example countryId aswell as country itself). The error i get when using countryId is:
Unknown arg countryId in update.countryId for type ShowUpdateInput. Did you mean country?
if i use country:
Unknown arg country in update.country.connect.country for type CountryWhereUniqueInput. Did you mean code?
I also tried to privde the country without the connect like so:
country: country,
what is the correct way to do that?
I wonder why my model (the Like-model) does not work as I expect it to.
Maybe someone can explain?
model User {
id Int #id #default(autoincrement())
likes Like[]
}
model Like {
fromUser User #relation(fields: [fromUserId] references: [id])
fromUserId Int
toUser User #relation(fields: [toUserId] references: [id])
toUserId Int
##id([fromUserId, toUserId])
}
The error reads: Error validating: This line is not a valid field or attribute definition.
It points at fromUser User #relation(fields: [fromUserId] references: [id]) and toUser User #relation(fields: [toUserId] references: [id]).
You would need to model your relations in the following manner:
model User {
id Int #id #default(autoincrement())
likedUsers Like[] #relation("likedUsers")
usersWhoLiked Like[] #relation("usersWhoLiked")
}
model Like {
id Int #id #default(autoincrement())
likedUser User? #relation("likedUsers", fields: [likedUserId], references: [id])
likedUserId Int?
userWhoLiked User? #relation("usersWhoLiked", fields: [userWhoLikedId], references: [id])
userWhoLikedId Int?
}
Whenever you have more than 1 relation to a model you need to provide a relation name to disambiguate the relation.
Also you need to store which users you have liked and who liked the current user. So you would need two relations for this.
Missing commas.
The solution might look like this:
model User {
id Int #id #default(autoincrement())
likes Like[]
}
model Like {
fromUser User #relation(fields: [fromUserId], references: [id])
fromUserId Int
toUser User #relation(fields: [toUserId], references: [id])
toUserId Int
##id([fromUserId, toUserId])
}
How can query relationships in Prisma? I have the following schema:
model User {
id Int #id #default(autoincrement())
name String?
profile Profile
}
model Profile {
id Int #id #default(autoincrement())
user User #relation(fields: [userId], references: [id])
userId Int
}
How can I query a Profile for a specific User?
Found the answer myself:
prisma.user.findUnique({ where: { id: 42 }}).profile()