Advanced Usage
Note
Adapted from the Prisma Client Go documentation
In the quickstart, we have created a simple post model and ran a few queries. However, Prisma and the Python client are designed to work with relations between models.
We already created a post model, such as for a blog. Let's assume we want to add comments to a post, and connect these models in a way so we can rely on SQL's foreign keys and the Python client's ability to work with relations.
So let's introduce a new comment model with a 1 to many relationship with the Post model:
model Post {
...
comments Comment[]
}
model Comment {
id String @default(cuid()) @id
created_at DateTime @default(now())
content String
post Post @relation(fields: [post_id], references: [id])
post_id String
}
Full Prisma Schema
datasource db {
// could be postgresql or mysql
provider = "sqlite"
url = "file:dev.db"
}
generator db {
provider = "prisma-client-py"
recursive_type_depth = 5
}
model Post {
id String @id @default(cuid())
created_at DateTime @default(now())
updated_at DateTime @updatedAt
title String
published Boolean
desc String?
comments Comment[]
}
model Comment {
id String @id @default(cuid())
created_at DateTime @default(now())
content String
post Post @relation(fields: [post_id], references: [id])
post_id String
}
Whenever you make changes to your model, migrate your database and re-generate your prisma code:
# apply migrations
prisma migrate dev --name "add comment model"
# generate
prisma generate
In order to create comments, we can either create a post, and then connect that post when creating a comment or create a post while creating the comment.
post = await db.post.create({
'title': 'My new post',
'published': True,
})
print(f'post: {post.json(indent=2)}\n')
first = await db.comment.create({
'content': 'First comment',
'post': {
'connect': {
'id': post.id,
},
},
})
print(f'first comment: {first.json(indent=2)}\n')
second = await db.comment.create({
'content': 'Second comment',
'post': {
'connect': {
'id': post.id,
},
},
})
print(f'second comment: {second.json(indent=2)}\n')
Alternative method
first = await db.comment.create(
data={
'content': 'First comment',
'post': {
'create': {
'title': 'My new post',
'published': True,
},
},
},
include={'post': True}
)
second = await db.comment.create({
'content': 'Second comment',
'post': {
'connect': {
'id': first.post.id
}
}
})
Now that a post and comments have been created, you can query for them as follows:
# find all comments on a post
comments = await db.comment.find_many(
where={
'post_id': post.id
}
)
print(f'comments of post with id {post.id}')
for comment in comments:
print(comment.json(indent=2))
# find at most 3 comments on a post
filtered = await db.comment.find_many(
where={
'post_id': post.id
},
take=3
)
print(f'filtered comments of post with id {post.id}')
for comment in filtered:
print(comment.json(indent=2))
Prisma also allows you to fetch multiple things at once. Instead of doing complicated joins, you can fetch a post and a few of their comments in just a few lines and with full type-safety:
# fetch a post and 3 of its comments
post = await db.post.find_unique(
where={
'id': post.id,
},
include={
'comments': {
'take': 3,
},
},
)