25
loading...
This website collects cookies to deliver better user experience
If you didn't get a chance to read through the previous article, I highly recommend doing so as this tutorial will build off of our results there.
create
, createMany
findFirst
, findMany
, findUnique
update
, updateMany
, upsert
delete
, deleteMany
import { PrismaClient } from '@prisma/client'
const prisma = new PrismaClient()
async function main() {
const users = await prisma.user.findMany();
console.log(JSON.stringify(users));
}
main()
.catch( e => { throw e })
.finally( async () => await prisma.$disconnect() )
Prisma Client
that was generated off of the schema we put together, which currently contains a User
model. User
table was added manually via Prisma Studio.User
table via the code rather than the Prisma Studio UI!create
and createMany
.create
function.data
key and a select
key. It returns a Promise with a User
object.Prisma.UserCreateInput
Prisma.UserSelect
select
key allows you to define which fields you want to return if you don’t want the whole object.import { PrismaClient } from '@prisma/client'
const prisma = new PrismaClient()
async function main() {
const newUser = await prisma.user.create({
data: {
firstName: 'Sabin',
lastName: 'Adams',
email: '[email protected]'
},
select: {
id: true,
email: true
}
})
console.log(newUser);
}
main()
.catch( e => { throw e })
.finally( async () => await prisma.$disconnect() )
You may have noticed if you ran the function that the new user's ID was automatically generated because in our schema.prisma
file we set that field to autoincrement()
User
model, but what if you aren't sure what a User
looks like or are working on a larger team of people who may not know which fields are required and aren't? User
. createUser
function.import { PrismaClient, Prisma, User } from '@prisma/client'
const prisma = new PrismaClient()
async function createUser(
data: Prisma.UserCreateInput
): Promise<User> {
return await prisma.user.create({
data,
select: {
id: true,
email: true
}
})
}
data
parameter that needs to be of the type Prisma.UserCreateInput
and returns a Promise that provides a User
when resolved. These were made by Prisma based on your models.User
model (we are picking out the id and email fields). User
model, also called a Partial
which is a TypeScript utility type.async function createUser(
data: User.UserCreateInput
): Promise<Partial<User>> {...}
createUser
function in your main()
function and see what the IntelliSense does:This function is not yet supported in SQLite
createMany
is for. create
function. The difference is that its data
key takes in an array of Objects matching the model's type instead of a single object. Prisma.UserCreateManyInput[]
Boolean
BatchPayload
type and looks something like:{ "count": 3 }
async function createUsers(
data: Prisma.UserCreateManyInput[]
): Promise<Prisma.BatchPayload> {
return await prisma.user.createMany({ data })
}
const results = await createUsers([
{
email: '[email protected]',
firstName: 'Sabin',
lastName: 'Adams'
},
{
email: '[email protected]',
firstName: 'Jimmy',
lastName: 'John'
}
]);
// result = { count: 2 }
createMany
function also accepts the key skipDuplicates
which can be true
or false
. If set to true, it will not create duplicate rows.await prisma.user.createMany({
data: [ ... your data ],
skipDuplicates: true
})
I will cover the rest of the available types Prisma generates in the future, but for now just know each CRUD function has useful types similar to the ones I’ve described here
findFirst
. If you are curious about all of the options available check out this function's docs
import { PrismaClient, Prisma } from '@prisma/client'
const prisma = new PrismaClient()
const oldUser = await prisma.user.findFirst({
where: {
age: {
gt: 20
}
}
})
age
field to our User
model in the database schema. Here is the updated model in schema.prisma
model User {
id Int @id @default(autoincrement())
firstName String
lastName String
email String
age Int?
}
User
from the function.where
to filter down your data and configure what you want returned from the function. age
before selecting the first matching record using the orderBy
option.const oldestUserBelowTwenty = await prisma.user.findFirst({
orderBy: {
age: 'desc'
},
where: {
age: {
lt: 20
}
}
})
findUnique
, except rather than grabbing the first matching record it returns ALL matching records. const usersOverTwenty = await prisma.user.findMany({
select: {
id: true
},
orderBy: {
lastName: 'asc'
},
where: {
age: {
gt: 20
}
}
})
findFirst
function, returns a single record. The difference here, though, is that the where
filter only allows you to search on fields that are unique. User
model.model User {
id Int @id @default(autoincrement())
firstName String
lastName String
email String
age Int?
}
@id
fields are examples of unique fields. Below is a full list of attributes that signify a field is unique.@id
: Attribute signifying the Primary Key of your table (if one exists)@@id
: Compound Identifier@unique
: Attribute signifying a field that should be unique
@@unique
: Unique IdentifierfindUnique
function in actionconst user = await prisma.user.findUnique({
where: {
id: 3
}
})
User
by it's unique identifier id
. We want the user with an id
of 3. As you are typing the filter out, you will notice your IntelliSense does not list each of the model's fields as available options. It only allows you to filter on the unique field in our model.select
which fields to include in the returned object and many other options just like the other "read" functions.upsert
. update
function allows us to update a single record. You can specify which record to update the same way the findUnique
function determines which record to grab. It bases its query off of only the unique identifiers of that model.const user = await prisma.user.update({
select: {
id: true,
age: true
},
where: {
id: 4
},
data: {
age: 7
}
})
id
is 4. It will set the age
of that user to 7 and return an object containing the id
and age
fields.select
key, the entire User
object would have been returned. Option | Description |
---|---|
increment | Adds the provided value to the existing value |
decrement | Subtracts the provided value number from the existing value |
multiply | Multiplies the existing value by the value supplied |
divide | Divides the existing value by the value supplied |
These options are also available on the other update functions
age
in the database. We could use the following query to increment her age by 1 and get the user's record back.const user = await prisma.user.update({
where: {
id: 4
},
data: {
age: {
increment: 1
}
}
})
updateMany
function. This function's input takes the following options:where
: The search query to find which records to updatedata
: The updates we want to makeupdate
function though. Similar to createMany
, we instead get back a Prisma.BatchPayload
object, which is of the format below. The count
key is a count of how many records actually received updates.{ "count": number }
lastName
of Adams and Williams to have the same email address.const results = await prisma.user.updateMany({
where: {
lastName: {
in: ['Adams', 'Williams']
}
},
data: {
email: '[email protected]'
}
})
// results could be { "count": 5 } if five records were updated
where
statments: in
. This allows us to pass in an array of values to match a field against.upsert
is for!const user: User = {
id: 3
firstName: 'Johnny',
lastName: 'Bravo',
email: '[email protected]',
age: 25
}
const user = await prisma.user.upsert({
select: { id: true },
where: {
id: userId
},
update: {
age: user.age
},
create: user
})
user
details. We can pretend someone maybe made some changes to their account and hit Save. These are the values that got sent to our server.id
and update the age value of that record.An upsert's where
option filters on unique identifiers only
saveUser
endpoint that handles creating new users and updating existing ones? With our upsert
we can specify that if no matches were made via the where
clause we should run the create
function instead with some data (in this case the whole user
data object that was sent).select
option we've specified that we want to get the ID of the updated (or created) user back. If this was left out we'd get the whole User
object. delete
function does exactly what it sounds like it would do, it deletes a record of data in your table. where
: The where option filters on unique fields onlyselect
: This allows you to select data from the record you are deleting
const deleted = await prisma.user.delete({
where: {
id: 3
},
select: {
email: true
}
})
User
with the id
of 3. We are also returning the email
of this user to do some post-processing with afterwards (or something like that...).select
blank we would get back the entire User
record we deleted.deleteMany
. This is a pretty simple one and follows a lot of the conventions we've seen above.where
option. This allows us to filter down the the records we want to delete. Prisma.BatchPayload
object containing the count of records that were deleted.const results = await prisma.user.deleteMany({
where: {
id: {
notIn: [1,3,4]
},
email: {
endsWith: '@gmail.com'
}
}
})
id
s are not one, three, or four. It also only deletes the record if it has a @gmail.com
email.Prisma Client
, but we will certainly be digging deeper in future articles.