CUID Not Auto-Generating

I'm trying to write a seed script to populate my database with mock data, but for whatever reason, I'm getting a null constraint error for the primary key ('_id'), even though my schema is set to autogenerate this. It generates them just fine within my actual app, but it's not for my seed script for whatever reason. Any ideas? (Snippets in thread.)
6 Replies
Prisma AI Help
Prisma AI Helpā€¢2w ago
Skipping coffee for instant knowledge! Let's brew that AI answer now.
KinglyEndeavors
KinglyEndeavorsOPā€¢2w ago
async function seedDatabase() {
const { range } = require('lodash');
const [{ PrismaClient, TicketStatus }, { faker }] = await Promise.all([
import('@prisma/client'),
import('@faker-js/faker'),
]);

const prisma = new PrismaClient();

try {
const fakeUsers: UserSeed[] = range(10).map(
(): UserSeed =>
({
email: faker.internet.email(),
name: faker.person.fullName(),
} as const),
);

console.log('SEEDING DATABASE...');

await prisma.$connect();
await prisma.$transaction(async () => {
await prisma.ticket.deleteMany();
await prisma.user.deleteMany();

const createdUserIDs: Pick<User, 'id'>[] = await prisma.user.createManyAndReturn({
select: { id: true },
data: fakeUsers,
skipDuplicates: true,
});

for (const _ of range(50)) {
const data: Prisma.TicketCreateInput = {
title: faker.lorem.sentence(),
status: faker.helpers.enumValue(TicketStatus),
priority: faker.number.int({ min: 1, max: 5 }),
description: faker.lorem.paragraph(),
};

if (faker.datatype.boolean()) {
const { id } = faker.helpers.arrayElement(createdUserIDs);
data.assignedTo = { connect: { id } };
}

await prisma.ticket.create({
data,
});
}
});

await prisma.$disconnect();

console.log('DATABASE SEEDING COMPLETE!!!');
process.exit(0);
} catch (error) {
console.error(error);
await prisma.$disconnect();
process.exit(1);
} finally {
await prisma.$disconnect();
}
}
async function seedDatabase() {
const { range } = require('lodash');
const [{ PrismaClient, TicketStatus }, { faker }] = await Promise.all([
import('@prisma/client'),
import('@faker-js/faker'),
]);

const prisma = new PrismaClient();

try {
const fakeUsers: UserSeed[] = range(10).map(
(): UserSeed =>
({
email: faker.internet.email(),
name: faker.person.fullName(),
} as const),
);

console.log('SEEDING DATABASE...');

await prisma.$connect();
await prisma.$transaction(async () => {
await prisma.ticket.deleteMany();
await prisma.user.deleteMany();

const createdUserIDs: Pick<User, 'id'>[] = await prisma.user.createManyAndReturn({
select: { id: true },
data: fakeUsers,
skipDuplicates: true,
});

for (const _ of range(50)) {
const data: Prisma.TicketCreateInput = {
title: faker.lorem.sentence(),
status: faker.helpers.enumValue(TicketStatus),
priority: faker.number.int({ min: 1, max: 5 }),
description: faker.lorem.paragraph(),
};

if (faker.datatype.boolean()) {
const { id } = faker.helpers.arrayElement(createdUserIDs);
data.assignedTo = { connect: { id } };
}

await prisma.ticket.create({
data,
});
}
});

await prisma.$disconnect();

console.log('DATABASE SEEDING COMPLETE!!!');
process.exit(0);
} catch (error) {
console.error(error);
await prisma.$disconnect();
process.exit(1);
} finally {
await prisma.$disconnect();
}
}
generator client {
provider = "prisma-client-js"
}

datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}

model User {
id String @id @default(cuid()) @map("_id")
email String @unique @db.VarChar(255)
name String @db.VarChar(255)
createdAt DateTime @default(now()) @map("created_at") @db.Timestamp()
updatedAt DateTime @updatedAt @map("updated_at") @db.Timestamp()
Ticket Ticket[]

@@index([name])
@@map("users")
}

enum TicketStatus {
OPEN
ASSIGNED
IN_PROGRESS
COMPLETED
}

model Ticket {
id String @id @default(cuid()) @map("_id")
title String @db.VarChar(255)
description String? @db.Text()
assignedTo User? @relation(fields: [id], references: [id], map: "assigned_to", onDelete: Restrict)
status TicketStatus @default(OPEN)
priority Int @default(0) @db.SmallInt()
createdAt DateTime @default(now()) @map("created_at") @db.Timestamp()
updatedAt DateTime @updatedAt @map("updated_at") @db.Timestamp()

@@map("tickets")
}
generator client {
provider = "prisma-client-js"
}

datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}

model User {
id String @id @default(cuid()) @map("_id")
email String @unique @db.VarChar(255)
name String @db.VarChar(255)
createdAt DateTime @default(now()) @map("created_at") @db.Timestamp()
updatedAt DateTime @updatedAt @map("updated_at") @db.Timestamp()
Ticket Ticket[]

@@index([name])
@@map("users")
}

enum TicketStatus {
OPEN
ASSIGNED
IN_PROGRESS
COMPLETED
}

model Ticket {
id String @id @default(cuid()) @map("_id")
title String @db.VarChar(255)
description String? @db.Text()
assignedTo User? @relation(fields: [id], references: [id], map: "assigned_to", onDelete: Restrict)
status TicketStatus @default(OPEN)
priority Int @default(0) @db.SmallInt()
createdAt DateTime @default(now()) @map("created_at") @db.Timestamp()
updatedAt DateTime @updatedAt @map("updated_at") @db.Timestamp()

@@map("tickets")
}
> node prisma/seed.ts

(node:247163) ExperimentalWarning: Type Stripping is an experimental feature and might change at any time
(Use `node --trace-warnings ...` to show where the warning was created)
SEEDING DATABASE...
PrismaClientKnownRequestError:
Invalid `prisma.ticket.create()` invocation in
/home/kingofheroes/Projects/playgrounds/react-todo/prisma/seed.ts:49:37

46 data.assignedTo = { connect: { id } };
47 }
48
ā†’ 49 await prisma.ticket.create(
Null constraint violation on the fields: (`_id`)
at Un.handleRequestError (/home/kingofheroes/Projects/playgrounds/react-todo/node_modules/.pnpm/@[email protected][email protected][email protected][email protected]/node_modules/@prisma/client/runtime/library.js:121:7447)
at Un.handleAndLogRequestError (/home/kingofheroes/Projects/playgrounds/react-todo/node_modules/.pnpm/@[email protected][email protected][email protected][email protected]/node_modules/@prisma/client/runtime/library.js:121:6771)
at Un.request (/home/kingofheroes/Projects/playgrounds/react-todo/node_modules/.pnpm/@[email protected][email protected][email protected][email protected]/node_modules/@prisma/client/runtime/library.js:121:6478)
at async l (/home/kingofheroes/Projects/playgrounds/react-todo/node_modules/.pnpm/@[email protected][email protected][email protected][email protected]/node_modules/@prisma/client/runtime/library.js:130:9644)
at async /home/kingofheroes/Projects/playgrounds/react-todo/prisma/seed.ts:49:17
at async Proxy._transactionWithCallback (/home/kingofheroes/Projects/playgrounds/react-todo/node_modules/.pnpm/@[email protected][email protected][email protected][email protected]/node_modules/@prisma/client/runtime/library.js:130:8005)
at async seedDatabase (/home/kingofheroes/Projects/playgrounds/react-todo/prisma/seed.ts:26:9) {
code: 'P2011',
clientVersion: '6.4.1',
meta: { modelName: 'Ticket', constraint: [ '_id' ] }
> node prisma/seed.ts

(node:247163) ExperimentalWarning: Type Stripping is an experimental feature and might change at any time
(Use `node --trace-warnings ...` to show where the warning was created)
SEEDING DATABASE...
PrismaClientKnownRequestError:
Invalid `prisma.ticket.create()` invocation in
/home/kingofheroes/Projects/playgrounds/react-todo/prisma/seed.ts:49:37

46 data.assignedTo = { connect: { id } };
47 }
48
ā†’ 49 await prisma.ticket.create(
Null constraint violation on the fields: (`_id`)
at Un.handleRequestError (/home/kingofheroes/Projects/playgrounds/react-todo/node_modules/.pnpm/@[email protected][email protected][email protected][email protected]/node_modules/@prisma/client/runtime/library.js:121:7447)
at Un.handleAndLogRequestError (/home/kingofheroes/Projects/playgrounds/react-todo/node_modules/.pnpm/@[email protected][email protected][email protected][email protected]/node_modules/@prisma/client/runtime/library.js:121:6771)
at Un.request (/home/kingofheroes/Projects/playgrounds/react-todo/node_modules/.pnpm/@[email protected][email protected][email protected][email protected]/node_modules/@prisma/client/runtime/library.js:121:6478)
at async l (/home/kingofheroes/Projects/playgrounds/react-todo/node_modules/.pnpm/@[email protected][email protected][email protected][email protected]/node_modules/@prisma/client/runtime/library.js:130:9644)
at async /home/kingofheroes/Projects/playgrounds/react-todo/prisma/seed.ts:49:17
at async Proxy._transactionWithCallback (/home/kingofheroes/Projects/playgrounds/react-todo/node_modules/.pnpm/@[email protected][email protected][email protected][email protected]/node_modules/@prisma/client/runtime/library.js:130:8005)
at async seedDatabase (/home/kingofheroes/Projects/playgrounds/react-todo/prisma/seed.ts:26:9) {
code: 'P2011',
clientVersion: '6.4.1',
meta: { modelName: 'Ticket', constraint: [ '_id' ] }
Prisma AI Help
Prisma AI Helpā€¢2w ago
Based on the information provided in the knowledge sources, it appears that you're encountering an issue with CUID auto-generation in your seed script. This is a known issue that has been reported and discussed in Prisma's GitHub repository. Here are some insights and potential solutions: 1. CUID Generation Issue: The error you're experiencing is likely related to a problem with CUID generation in certain environments. This issue has been reported in GitHub Issue #14864 and GitHub Issue #14870. 2. Potential Workaround: As mentioned in one of the comments, changing the ID field from cuid() to autoincrement() might resolve the issue. For example:
model User {
id Int @id @default(autoincrement())
// other fields
}

model User {
id Int @id @default(autoincrement())
// other fields
}

This workaround has been reported to work in some cases. 3. Alternative Solution for MongoDB: If you're using MongoDB, you might consider using ObjectId instead of cuid(). According to the Prisma documentation on MongoDB, you can use the following schema:
model User {
id String @id @default(auto()) @map("_id") @db.ObjectId
// Other fields
}

model User {
id String @id @default(auto()) @map("_id") @db.ObjectId
// Other fields
}

This approach uses MongoDB's native ObjectId type and might avoid the CUID generation issue. 4. Manual ID Generation: As a last resort, you could consider manually generating IDs in your seed script. For MongoDB, you can use the bson package to generate valid ObjectIds:
import { ObjectId } from 'bson'

const id = new ObjectId()

import { ObjectId } from 'bson'

const id = new ObjectId()

It's important to note that the CUID generation issue seems to be environment-specific, which is why it works in your app but not in the seed script. If none of these solutions work, you might need to provide more details about your specific setup and environment for further troubleshooting. šŸ¤” Alright, thanks for letting us know that there's still some help needed. A team member will reply to you shortly. In the meantime, please let us know any additional info, questions, or which parts of the answer may need clarification.
Nurul
Nurulā€¢2w ago
Hi šŸ‘‹ In your ticket model, you seem to be using id model as both the primary key and the foreign key for the assignedTo relation. This causes the auto-generated cuid() for id to be overridden (or not set) when you try to connect a user, resulting in the null constraint violation. The solution could be to create a separate field (commonly named something like assignedToId) for the foreign key.
model Ticket {
id String @id @default(cuid()) @map("_id")
title String @db.VarChar(255)
description String? @db.Text()
assignedToId String? @map("assigned_to")
assignedTo User? @relation(fields: [assignedToId], references: [id], onDelete: Restrict)
status TicketStatus @default(OPEN)
priority Int @default(0) @db.SmallInt()
createdAt DateTime @default(now()) @map("created_at") @db.Timestamp()
updatedAt DateTime @updatedAt @map("updated_at") @db.Timestamp()

@@map("tickets")
}
model Ticket {
id String @id @default(cuid()) @map("_id")
title String @db.VarChar(255)
description String? @db.Text()
assignedToId String? @map("assigned_to")
assignedTo User? @relation(fields: [assignedToId], references: [id], onDelete: Restrict)
status TicketStatus @default(OPEN)
priority Int @default(0) @db.SmallInt()
createdAt DateTime @default(now()) @map("created_at") @db.Timestamp()
updatedAt DateTime @updatedAt @map("updated_at") @db.Timestamp()

@@map("tickets")
}
With this change, your auto-generated id remains solely the primary key, and the optional foreign key (assignedToId) is used for the relation.
KinglyEndeavors
KinglyEndeavorsOPā€¢2w ago
Oooooh! Yeah, that makes sense. lol Thanks! Yep -- that fixed it! šŸ™‚
Nurul
Nurulā€¢2w ago
Glad to hear that šŸ˜„

Did you find this page helpful?