I've been stuck on this problem for hours.
I'm trying to create an object linked by a many to many relationship.
However, I get this error when the function is invoked:
Unknown arg 0 in data.merchandises.create.0 for type ListingsMerchandisesCreateWithoutListingInput.
Argument merchandise for data.merchandises.create.merchandise is missing.
I don't know where that "0" comes from.
Thank you in advance for your help..
Full log of error:
Invalid `prisma[prismaModel].create()` invocation in
/app/node_modules/prisma-factory/dist/index.js:109:44
106 data = hooks.beforeCreate(data);
107 }
108 const prismaModel = (0, import_camel_case.camelCase)(modelName);
→ 109 let result = await prisma[prismaModel].create({
data: {
type: 'FOR_RENT',
name: 'consequatur',
merchandises: {
create: {
'0': {
merchandise: {
create: {
cosmetic: 'GOOD',
typology: 'NEW',
quantity: 76,
price: 80,
location: {
create: {
name: 'repellat',
line1: '600 Jerde Mews',
line2: 'Apt. 517',
line3: '79414 Lenore Harbor',
line4: 'placeat',
city: 'Port Astridshire',
postalCode: '47459-8067',
state: 'North Carolina',
country: 'Antigua and Barbuda',
other: 'iste'
}
},
user: {
create: {
email: 'Neoma41#gmail.com',
firstName: 'Casimir',
lastName: 'Kub'
}
},
product: {
create: {
name: 'Luxurious Steel Keyboard',
description: 'The Nagasaki Lander is the trademarked name of several series of Nagasaki sport bikes, that started with the 1984 ABC800J',
barcode: 'r0h7w9h1d',
barcodeType: 'EAN13',
brand: 'Bespoke',
model: 'Countach',
lenght: 25,
width: 57,
weight: 11,
capacity: 62,
impactUnit: 'UNIT',
manufacturingImpact: 31,
destructiveImpact: 81
}
}
}
}
},
+ merchandise: {
+ create?: MerchandiseCreateWithoutListingsInput | MerchandiseUncheckedCreateWithoutListingsInput,
+ connectOrCreate?: MerchandiseCreateOrConnectWithoutListingsInput,
+ connect?: MerchandiseWhereUniqueInput
+ }
}
}
}
})
Unknown arg `0` in data.merchandises.create.0 for type ListingsMerchandisesCreateWithoutListingInput.
Argument merchandise for data.merchandises.create.merchandise is missing.
The factory:
import { createFactory } from 'prisma-factory';
import { faker } from '#faker-js/faker';
import {
BarcodeType,
Cosmetic,
ImpactUnit,
Listing,
ListingType,
Prisma,
Typology,
} from '#prisma/client';
const DEFAULT_ATTRIBUTES = {
type: ListingType.FOR_RENT,
name: faker.lorem.word(),
merchandises: {
create: [
{
merchandise: {
create: {
cosmetic: Cosmetic.GOOD,
typology: Typology.NEW,
quantity: Number(faker.random.numeric(2)),
price: Number(faker.random.numeric(2)),
location: {
create: {
name: faker.lorem.word(),
line1: faker.address.streetAddress(),
line2: faker.address.secondaryAddress(),
line3: faker.address.streetAddress(),
line4: faker.lorem.word(),
city: faker.address.city(),
postalCode: faker.address.zipCode(),
state: faker.address.state(),
country: faker.address.country(),
other: faker.lorem.word(4),
},
},
user: {
create: {
email: faker.internet.email(),
firstName: faker.name.firstName(),
lastName: faker.name.lastName(),
},
},
product: {
create: {
name: faker.commerce.productName(),
description: faker.commerce.productDescription(),
barcode: faker.random.alphaNumeric(9),
barcodeType: BarcodeType.EAN13,
brand: faker.commerce.productAdjective(),
model: faker.vehicle.model(),
lenght: Number(faker.random.numeric(2)),
width: Number(faker.random.numeric(2)),
weight: Number(faker.random.numeric(2)),
capacity: Number(faker.random.numeric(2)),
impactUnit: ImpactUnit.UNIT,
manufacturingImpact: Number(faker.random.numeric(2)),
destructiveImpact: Number(faker.random.numeric(2)),
},
},
},
},
},
],
},
};
export const ListingFactory = createFactory<Prisma.ListingCreateInput, Listing>(
'listing',
DEFAULT_ATTRIBUTES,
);
concerning schema:
model Listing {
id Int #id #default(autoincrement())
type ListingType
name String
merchandises ListingsMerchandises[]
availability Availability?
category Category? #relation(fields: [categoryId], references: [id])
categoryId Int?
createdAt DateTime #default(now())
updatedAt DateTime #updatedAt
deletedAt DateTime?
}
model Merchandise {
id Int #id #default(autoincrement())
cosmetic Cosmetic
typology Typology
quantity Int
price Int
productId Int
product Product #relation(fields: [productId], references: [id])
userId Int
user User #relation(fields: [userId], references: [id])
locationId Int
location Location? #relation(fields: [locationId], references: [id])
listings ListingsMerchandises[]
createdAt DateTime #default(now())
updatedAt DateTime #updatedAt
deletedAt DateTime?
}
model ListingsMerchandises {
listingId Int
listing Listing #relation(fields: [listingId], references: [id])
merchandiseId Int
merchandise Merchandise #relation(fields: [merchandiseId], references: [id])
##id([listingId, merchandiseId])
}
I tried several formats, I even tried a connect but without success.
No type errors are thrown
Related
so, i want to create a memory for a user and add the user to the memory api using prisma. in this user table and memory table are connected by a many to many relationship. They share a common table userMemory.
schema.prisma
model User {
userId String #id #default(uuid())
avatarUrl String?
bio String?
firstName String
lastName String?
dob DateTime
createdAt DateTime #default(now())
modifiedAt DateTime #default(now()) #updatedAt
createdBy String?
modifiedBy String?
followersCount BigInt #default(0)
followingCount BigInt #default(0)
memories UserMemory[]
}
model Memory {
memoryId String #id #default(uuid())
users UserMemory[]
latitude Float?
longitude Float?
createdAt DateTime #default(now())
modifiedAt DateTime #default(now()) #updatedAt
createdBy String?
modifiedBy String?
textHtml String?
mediaUrl String[]
}
This is my user services file
import { Injectable } from '#nestjs/common';
import { GraphQLError } from 'graphql/error';
import { PrismaService } from 'src/prisma/prisma.service';
import {
CreateUserInput,
OrderByInput,
UpdateUserInput,
} from 'src/types/graphql';
#Injectable()
export class UserService {
constructor(private prisma: PrismaService) {}
async create(createUserInput: CreateUserInput) {
try {
let user = await this.prisma.user.create({
data: createUserInput,
});
user = await this.prisma.user.update({
where: { userId: user.userId },
data: {
createdBy: user.userId,
modifiedBy: user.userId,
},
});
return user;
} catch (e) {
throw new GraphQLError('Error Occurred', {
extensions: { e },
});
}
}
}
This is my memories service file
import { Injectable } from '#nestjs/common';
import { GraphQLError } from 'graphql';
import { PrismaService } from 'src/prisma/prisma.service';
import { CreateMemoryInput, UpdateMemoryInput } from 'src/types/graphql';
#Injectable()
export class MemoriesService {
constructor(private prisma: PrismaService) {}
async create({ authorId, ...createMemoryInput }: CreateMemoryInput) {
try {
const user = await this.prisma.user.findUnique({
where: {
userId: authorId,
},
});
const memory = await this.prisma.memory.create({
data: {
...createMemoryInput,
createdBy: authorId,
modifiedBy: authorId,
users: {
create: [
{
user: {
connect: {
userId: authorId,
...user,
},
},
},
],
},
},
include: {
users: true,
},
});
return memory;
} catch (e) {
throw new GraphQLError('Error Occurred', {
extensions: { e },
});
}
}
async findOne(memoryId: string) {
try {
return await this.prisma.memory.findUnique({
where: {
memoryId,
},
include: {
users: true,
},
});
} catch (e) {
throw new GraphQLError('Error Occurred', {
extensions: { e },
});
}
}
}
my users type defination file
scalar Date
scalar URL
scalar Timestamp
scalar UUID
type User {
userId: UUID!
avatarUrl: URL
bio: String
firstName: String!
lastName: String
dob: Date
createdAt: Timestamp
modifiedAt: Timestamp
createdBy: UUID
modifiedBy: UUID
memories: [Memory]
}
input CreateUserInput {
firstName: String!
lastName: String
dob: Date!
}
type Mutation {
createUser(createUserInput: CreateUserInput!): User!
}
my memories type defination file
type Memory {
memoryId: UUID!
users: [User]
latitude: Float
longitude: Float
createdAt: Timestamp
modifiedAt: Timestamp
createdBy: UUID
modifiedBy: UUID
textHtml: String
mediaUrl: [String]
}
input CreateMemoryInput {
authorId: UUID!
latitude: Float
longitude: Float
textHtml: String
mediaUrl: [String]
}
type Query {
memories: [Memory]!
memory(memoryId: UUID!): Memory
}
type Mutation {
createMemory(createMemoryInput: CreateMemoryInput!): Memory!
}
this is my creat mutation query
mutation CreateMemory($createMemoryInput: CreateMemoryInput!) {
createMemory(createMemoryInput: $createMemoryInput) {
createdAt
createdBy
latitude
longitude
mediaUrl
memoryId
modifiedAt
modifiedBy
textHtml
users {
accountType
avatarUrl
bio
createdAt
createdBy
dob
firstName
gender
lastName
modifiedAt
modifiedBy
userId
}
}
}
so whenever i am creating a memoory against a user, i am getting this error, although data is population in data base.
{
"errors": [
{
"message": "Cannot return null for non-nullable field User.firstName.",
"locations": [
{
"line": 43,
"column": 7
}
],
"path": [
"memory",
"users",
0,
"firstName"
],
"extensions": {
"code": "INTERNAL_SERVER_ERROR",
"exception": {
"stacktrace": [
"Error: Cannot return null for non-nullable field User.firstName.",
" at completeValue (/Users/sohamnandi/Desktop/Projects/link-yatri-api/node_modules/graphql/execution/execute.js:594:13)",
" at executeField (/Users/sohamnandi/Desktop/Projects/link-yatri-api/node_modules/graphql/execution/execute.js:489:19)",
" at executeFields (/Users/sohamnandi/Desktop/Projects/link-yatri-api/node_modules/graphql/execution/execute.js:413:20)",
" at completeObjectValue (/Users/sohamnandi/Desktop/Projects/link-yatri-api/node_modules/graphql/execution/execute.js:914:10)",
" at completeValue (/Users/sohamnandi/Desktop/Projects/link-yatri-api/node_modules/graphql/execution/execute.js:635:12)",
" at /Users/sohamnandi/Desktop/Projects/link-yatri-api/node_modules/graphql/execution/execute.js:696:25",
" at Function.from (<anonymous>)",
" at completeListValue (/Users/sohamnandi/Desktop/Projects/link-yatri-api/node_modules/graphql/execution/execute.js:676:34)",
" at completeValue (/Users/sohamnandi/Desktop/Projects/link-yatri-api/node_modules/graphql/execution/execute.js:607:12)",
" at executeField (/Users/sohamnandi/Desktop/Projects/link-yatri-api/node_modules/graphql/execution/execute.js:489:19)"
]
}
}
}
],
"data": {
"memory": {
"createdAt": 1674566005576,
"createdBy": "5a147521-a797-4587-b75f-a07f5b00430e",
"latitude": null,
"longitude": null,
"mediaUrl": [],
"memoryId": "0f2a1a5a-298b-4b8c-a526-7e06e0d4b126",
"modifiedAt": 1674566005576,
"modifiedBy": "5a147521-a797-4587-b75f-a07f5b00430e",
"textHtml": null,
"users": [
null
]
}
}
}
I have comics which has many writers, artists and characters and i'm trying to join everything together in prisma, but struggling to understand what I'm doing wrong.
Comic schema:
model comics {
uniqueCoverId String #id
name String
artists comic_contributors[] #relation("artists")
writers comic_contributors[] #relation("writers")
}
Artists schema
model comic_artists {
id String #id #default(uuid())
name String?
comics comic_contributors[]
}
Writers schema
model comic_writers {
id String #id #default(uuid())
name String?
comics comic_contributors[]
}
Intermediary table
model comic_contributors {
writer_id String #unique
writer comic_writers? #relation("writers", fields: [writer_id], references: [id])
artist_id String #unique
artist comic_artists? #relation("artists", fields: [artist_id], references: [id])
##id([writer_id, artist_id])
}
When I try to format prisma it returns the errors
error: Field "comics" is already defined on model "comic_contributors".
comicsUniqueCoverId String?
comics comics? #relation(fields: [comicsUniqueCoverId], references: [uniqueCoverId])
error: Field "comicsUniqueCoverId" is already defined on model "comic_contributors".
comics comics? #relation(fields: [comicsUniqueCoverId], references: [uniqueCoverId])
comicsUniqueCoverId String?
Any suggestions on what I'm doing wrong please?
You don't need to explicit a many-to-many relationship table, Prisma is doing it for you!
Prisma implicit many-to-many
You only have to say:
model comics {
uniqueCoverId String #id
name String
artists comic_artists[]
writers comic_writers[]
}
model comic_artists {
id String #id #default(uuid())
name String?
comics comics[]
}
model comic_writers {
id String #id #default(uuid())
name String?
comics comics[]
}
and Prisma will create hidden relationship tables as
_comic_artitsTocomics
column A -> comic_artits.id
column B -> comics.uniqueCoverId
_comic_writersTocomics
column A -> comic_writers.id
column B -> comics.uniqueCoverId
This allow you to do
const comic = await prisma.comics.findUnique({
where: {
uniqueCoverId: 'UniqueCoverId',
},
include: {
artists: true,
writers: true,
},
});
And comic will looks like
{
uniqueCoverId: 'UniqueCoverId',
name: 'Name',
artists: [
{ id: '210059e6-00ab-448c-aea9-b706251ade52', name: 'Artist1' },
{ id: '38cd8efa-2a66-4fe5-ad47-ec4f511647c0', name: 'Artist2' },
{ id: '86d6c908-f17b-4fbd-b0ee-c314f06aeaa9', name: 'Artist3' }
],
writers: [
{ id: '9cf97bf4-9c43-4579-924b-15a7f5dcb3f9', name: 'Writer1' },
{ id: 'afe6eb2d-6d69-44f2-a491-14827dc94e66', name: 'Writer2' },
{ id: 'cdac61cf-339d-460d-960b-6581fa2d7a57', name: 'Writer3' }
]
}
Prisma explicit many-to-many
But if you really need an explicit many-to-many relationship to add some data on the relation it will looks like this schema
model comics {
uniqueCoverId String #id
name String
artists comic_artistsOncomics[]
writers comic_writersOncomics[]
}
model comic_artists {
id String #id #default(uuid())
name String?
comics comic_artistsOncomics[]
}
model comic_artistsOncomics {
uniqueCoverId String
comic comics #relation(fields: [uniqueCoverId], references: [uniqueCoverId])
artistId String
artist comic_artists #relation(fields: [artistId], references: [id])
// Some data
##id([uniqueCoverId, artistId])
}
model comic_writers {
id String #id #default(uuid())
name String?
comics comic_writersOncomics[]
}
model comic_writersOncomics {
uniqueCoverId String
comic comics #relation(fields: [uniqueCoverId], references: [uniqueCoverId])
writerId String
writer comic_writers #relation(fields: [writerId], references: [id])
// Some data
##id([uniqueCoverId, writerId])
}
The previous findUnique will now looks like
const test = await prisma.comics.findUnique({
where: {
uniqueCoverId: 'uniqueCoverId',
},
include: {
artists: {
include: {
artist: true,
},
},
writers: {
include: {
writer: true,
},
},
},
});
And the result
{
uniqueCoverId: "UniqueCoverId",
name: "Name",
artists: [
{
uniqueCoverId: "UniqueCoverId",
artistId: "210059e6-00ab-448c-aea9-b706251ade52",
artist: {
id: "210059e6-00ab-448c-aea9-b706251ade52",
name: "Artist1",
},
},
{
uniqueCoverId: "UniqueCoverId",
artistId: "38cd8efa-2a66-4fe5-ad47-ec4f511647c0",
artist: {
id: "38cd8efa-2a66-4fe5-ad47-ec4f511647c0",
name: "Artist2",
},
},
{
uniqueCoverId: "UniqueCoverId",
artistId: "86d6c908-f17b-4fbd-b0ee-c314f06aeaa9",
artist: {
id: "86d6c908-f17b-4fbd-b0ee-c314f06aeaa9",
name: "Artist3",
},
},
],
writers: [
{
uniqueCoverId: "UniqueCoverId",
writerId: "9cf97bf4-9c43-4579-924b-15a7f5dcb3f9",
writer: {
id: "9cf97bf4-9c43-4579-924b-15a7f5dcb3f9",
name: "Writer1",
},
},
{
uniqueCoverId: "UniqueCoverId",
writerId: "afe6eb2d-6d69-44f2-a491-14827dc94e66",
writer: {
id: "afe6eb2d-6d69-44f2-a491-14827dc94e66",
name: "Writer2",
},
},
{
uniqueCoverId: "UniqueCoverId",
writerId: "cdac61cf-339d-460d-960b-6581fa2d7a57",
writer: {
id: "cdac61cf-339d-460d-960b-6581fa2d7a57",
name: "Writer3",
},
},
],
}
EDIT FOR YOU TO TEST
model comics {
id String #id #default(uuid())
uniqueCoverId String #unique
name String
artists comic_artists[]
writers comic_writers[]
}
model comic_artists {
id String #id #default(uuid())
name String?
comics comics[]
}
model comic_writers {
id String #id #default(uuid())
name String?
comics comics[]
}
How to filter a relation nested after m2m relation?
Unfortunately as for 2022-11 in Prisma documentation there isn't any info about that.
Schema.prisma:
model Entity {
id Int #id #default(autoincrement())
name String
service_entity_m2m ServiceEntityM2m[]
}
model Service {
id Int #id #default(autoincrement())
service_entity_m2m ServiceEntityM2m[]
}
model ServiceEntityM2m {
id Int #id #default(autoincrement())
entity_id Int
entity Entity #relation(fields: [entity_id], references: [id])
service_id Int
service Service #relation(fields: [service_id], references: [id])
}
Schema.graphql:
type Entity {
id: ID!
name: String
}
type Service {
id: ID!
service_entity_m2m: [ServiceEntityM2m]
}
type ServiceEntityM2m {
id: ID!
entity: Entity!
service: Service!
}
seeder:
// services
{
id: 1
}
// service_entity_m2m:
{
id: 1,
service_id: 1,
entity_id: 1
},
{
id: 2,
service_id: 1,
entity_id: 2
}
// entities
{
id: 1,
name: "XYZ"
},
{
id: 2,
name: "Test"
}
This code:
context.prisma.service.findMany({
where: { service_entity_m2m: { some: { entity: { name: { contains: "Test" } } } } },
include: { service_entity_m2m: { include: { entity: true } } },
})
returns both entities:
[
{
id: 1,
service_entity_m2m:
[
{
id: 1,
entity: {
id: 1,
name: "XYZ"
}
},
{
id: 2,
entity: {
id: 2,
name: "Test"
}
}
]
}
]
How to write a query that is going to return only one entity with the name "Test": ?
[
{
id: 1,
service_entity_m2m:
[
{
id: 2,
entity: {
id: 2,
name: "Test"
}
}
]
}
]
I have two tables User and Tasks and a user can have many tasks, however i want a query to return a particular task, fetching details for the task, with author and assigned to users from the user table, usually would be done using aliases. DB is mysql - Thanks
//schema.prisma
model User {
id Int #id #default(autoincrement())
taskby Task[] #relation("taskBy")
taskto Task[] #relation("taskTo")
}
model Task {
id Int #id #default(autoincrement())
created_at DateTime #default(now())
updated_at DateTime #updatedAt
assigned_to_uid Int
assigned_by_uid Int
assigned_to User #relation("taskTo",fields: [assigned_to_uid], references: [id])
assigned_by User #relation("taskBy",fields: [assigned_by_uid], references: [id])
}
API:
if (id) {
res = await prisma.task.findUnique({
where: { id },
include: {
assigned_to: true
},
include: {
assigned_by: true
},
})
} else {...
Desired Response:
{
"id": 2,
"taskid": 2,
"assigned_to_uid": 1,
"assigned_by_uid": 2,
"assigned_by": {
"id": 2,
"firstName": "user2",
},
"assigned_to": {
"id": 1
"firstName": "user1",
},
}
You should be able to get the desired response by using the below query:
if (id) {
const response = await prisma.task.findUnique({
where: { id },
include: {
assigned_to: true,
assigned_by: true,
},
});
console.log(response);
}
Response for the above query:
{
id: 1,
created_at: 2022-02-28T07:22:06.917Z,
updated_at: 2022-02-28T07:22:06.918Z,
assigned_to_uid: 2,
assigned_by_uid: 1,
assigned_to: { id: 2, firstName: 'Jane', lastName: 'Doe' },
assigned_by: { id: 1, firstName: 'John', lastName: 'Doe' }
}
I am trying to create and connect a record in a Prisma many to many relationship, but the connection part is not working for me.
Here are my Prisma models:
model Ingredient {
id Int #id #default(autoincrement())
name String
createdAt DateTime #default(now())
calories Int
protein Int
fat Int
carbs Int
netCarbs Int
metricQuantity Int
metricUnit String
imperialQuantity Int
imperialUnit String
recipes IngredientsOnRecipes[]
categories CategoriesOnIngredients[]
}
model IngredientCategory {
id Int #id #default(autoincrement())
name String
ingredients CategoriesOnIngredients[]
}
model CategoriesOnIngredients {
ingredient Ingredient #relation(fields: [ingredientId], references: [id])
ingredientId Int // relation scalar field (used in the `#relation` attribute above)
ingredientCategory IngredientCategory #relation(fields: [ingredientCategoryId], references: [id])
ingredientCategoryId Int // relation scalar field (used in the `#relation` attribute above)
assignedAt DateTime #default(now())
##id([ingredientId, ingredientCategoryId])
}
Here is the primsa query I am running:
const ingredient = await prisma.ingredient.create({
data: {
name: title,
metricQuantity: parseInt(quantityMetric),
metricUnit: unitMetric,
imperialQuantity: parseInt(quantityImperial),
imperialUnit: unitImperial,
calories: parseInt(calories),
netCarbs: parseInt(netCarbs),
carbs: parseInt(carbs),
protein: parseInt(protein),
fat: parseInt(fat),
categories: {
ingredientcategory: {
connect: { id: parseInt(categoryId) },
},
},
},
});
Creating a new ingredient works perfectly, but when I add this section:
categories: {
ingredientcategory: {
connect: { id: parseInt(categoryId) },
},
},
I get the following error:
Unknown arg ingredientcategory in data.categories.ingredientcategory for type CategoriesOnIngredientsCreateNestedManyWithoutIngredientInput. Did you mean createMany? Available args:
type CategoriesOnIngredientsCreateNestedManyWithoutIngredientInput {
create?: CategoriesOnIngredientsCreateWithoutIngredientInput | List | CategoriesOnIngredientsUncheckedCreateWithoutIngredientInput | List
connectOrCreate?: CategoriesOnIngredientsCreateOrConnectWithoutIngredientInput | List
createMany?: CategoriesOnIngredientsCreateManyIngredientInputEnvelope
connect?: CategoriesOnIngredientsWhereUniqueInput | List
}
You can try executing the following:
const { PrismaClient } = require('#prisma/client')
const prisma = new PrismaClient()
const saveData = async () => {
const ingredient = await prisma.ingredient.create({
data: {
name: 'ingredient1',
categories: {
create: {
ingredientCategory: {
create: {
name: 'category1',
},
}
}
},
},
select: {
id: true,
name: true,
categories: {
select: {
ingredientId: true,
ingredientCategory: true,
}
},
},
});
console.log(JSON.stringify(ingredient, null, 2));
}
saveData()
And you will have the following:
I managed to get it to work, I had missed create:{} from my Prisma query.
const ingredient = await prisma.ingredient.create({
data: {
name: title,
metricQuantity: parseInt(quantityMetric),
metricUnit: unitMetric,
imperialQuantity: parseInt(quantityImperial),
imperialUnit: unitImperial,
calories: parseInt(calories),
netCarbs: parseInt(netCarbs),
carbs: parseInt(carbs),
protein: parseInt(protein),
fat: parseInt(fat),
categories: {
create: {
ingredientCategory: {
connect: { id: parseInt(categoryId) },
},
},
},
},
});