https://github.com/fahimahammed/prismahandson
Welcome to PrismaHandsOn – your go-to resource for hands-on learning with Prisma ORM! Whether you're a beginner or an experienced developer looking to level up your skills, this repository is designed to guide you through the practical aspects of using Prisma in real-world scenarios.
https://github.com/fahimahammed/prismahandson
prisma-client prisma-migration prisma-orm
Last synced: about 1 year ago
JSON representation
Welcome to PrismaHandsOn – your go-to resource for hands-on learning with Prisma ORM! Whether you're a beginner or an experienced developer looking to level up your skills, this repository is designed to guide you through the practical aspects of using Prisma in real-world scenarios.
- Host: GitHub
- URL: https://github.com/fahimahammed/prismahandson
- Owner: fahimahammed
- Created: 2024-01-07T15:06:10.000Z (over 2 years ago)
- Default Branch: main
- Last Pushed: 2024-01-09T14:00:08.000Z (over 2 years ago)
- Last Synced: 2025-01-24T17:45:54.713Z (over 1 year ago)
- Topics: prisma-client, prisma-migration, prisma-orm
- Language: TypeScript
- Homepage:
- Size: 27.3 KB
- Stars: 2
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# PrismaHandsOn
Welcome to PrismaHandsOn – your go-to resource for hands-on learning with Prisma ORM! Whether you're a beginner or an experienced developer looking to level up your skills, this repository is designed to guide you through the practical aspects of using Prisma in real-world scenarios.
## Retrieving Data
### **Finding Records:**
**1. Finding All Records:**
- Use `prisma.model.findMany()` to retrieve all records of a specific model.
- Example: `const allUsers = await prisma.user.findMany()`
**2. Finding the First Record:**
- Use `prisma.model.findFirst()` to retrieve the first record matching your criteria.
- Example: `const firstUser = await prisma.user.findFirst({ where: { name: 'Alice' } })`
**3. Finding the First Record or Throwing an Error:**
- Use `prisma.model.findFirstOrThrow()` to retrieve the first record or throw an error if none is found.
- Example: `const user = await prisma.user.findFirstOrThrow({ where: { id: 1 } })`
**4. Finding a Unique Record:**
- Use `prisma.model.findUnique()` to retrieve a single record based on unique fields, such as an email address.
- Example: `const user = await prisma.user.findUnique({ where: { email: 'johndoe@example.com' } })`
**5. Finding a Unique Record or Throwing an Error:**
- Use `prisma.model.findUniqueOrThrow()` to retrieve a unique record or throw an error if none or multiple are found.
**6. Selecting Specific Fields:**
- Use the `select` option to fetch only the desired fields, improving performance.
- Example: `const users = await prisma.user.findMany({ select: { name: true, email: true } })`
### **Relation Queries:**
**1. Fluent API:**
- Prisma offers a fluent API for navigating relationships between models.
- Example: `const posts = await prisma.user.findUnique({ where: { email: 'johndoe@example.com' } }).posts()`
**2. Nested Reads:**
- Fetch related data in a single query using `include` or nested `select`.
- Example: `const userWithPosts = await prisma.user.findUnique({ where: { email: 'johndoe@example.com' }, include: { posts: true } })`
**3. Relation Filters:**
- Filter related records using `where` within nested reads.
- Example: `const userWithRecentPosts = await prisma.user.findUnique({ where: { email: 'johndoe@example.com' }, include: { posts: { where: { published: true } } } })`
### Filtering
**1. AND:**
- Combines multiple conditions using `and` within the `where` clause.
- Example: `const users = await prisma.user.findMany({ where: { age: { gt: 25 }, city: 'London' } })`
**2. Contains:**
- Checks if a string field contains a substring using `contains`.
- Example: `const posts = await prisma.post.findMany({ where: { title: { contains: 'Prisma' } } })`
**3. Equality:**
- Compares values for exact equality using `==`.
- Example: `const user = await prisma.user.findUnique({ where: { email: 'johndoe@example.com' } })`
**4. Greater Than:**
- Finds values greater than a specified value using `gt`.
- Example: `const expensiveProducts = await prisma.product.findMany({ where: { price: { gt: 100 } } })`
**5. In Array:**
- Checks if a value is present within an array using `in`.
- Example: `const activeUsers = await prisma.user.findMany({ where: { status: { in: ['active', 'pending'] } } })`
**6. NOT:**
- Negates a condition using `not`.
- Example: `const nonAdminUsers = await prisma.user.findMany({ where: { role: { not: 'admin' } } })`
**7. OR:**
- Combines multiple conditions using `or` within the `where` clause.
- Example: `const posts = await prisma.post.findMany({ where: { OR: [{ title: { contains: 'Prisma' } }, { content: { contains: 'ORM' } }] } })`
**8. Starts With:**
- Checks if a string field starts with a specific substring using `startsWith`.
- Example: `const users = await prisma.user.findMany({ where: { name: { startsWith: 'A' } } })`
### ****Pagination & Sorting****
**1. Cursor:**
- **Concept:** Cursor-based pagination relies on a unique value ("cursor") associated with each record, typically its ID or a timestamp. You request subsequent pages by providing the last known cursor in your query.
- **How it works:**
- Specify the `orderBy` option in your query to define the sorting order.
- Use the `first` or `last` option to set the number of records per page.
- Include the `cursor` argument with the value from the previous response for subsequent pages.
- **Advantages:**
- Efficient for large datasets: Only fetches needed pages, minimizing database load.
- Random access: Jump to any page regardless of order.
- **Disadvantages:**
- Requires consistent sorting: Cursor needs to be unique and ordered based on your sorting criteria.
- Complex logic: Managing and handling cursors can be intricate.
**2. Limit-Offset:**
- **Concept:** This traditional pagination method retrieves a specific number of records ("limit") starting from a given offset.
- **How it works:**
- Define the `skip` option to specify the offset (number of records to skip initially).
- Set the `take` option to determine the number of records to retrieve.
- **Advantages:**
- Simpler implementation: Easier to understand and set up.
- Predictable results: Consistent ordering within each page.
- **Disadvantages:**
- Inefficient for large datasets: Fetches all records up to the offset, even if not displayed.
- Limited access: Jumping to specific pages can be slow, needing multiple queries.
**3. Sort:**
- **Concept:** Defining the order in which your data is presented.
- **How it works:**
- Use the `orderBy` option in your query, specifying the field(s) and sorting direction (ascending/descending).
- You can sort by multiple fields, prioritize them using nested arrays.
- **Benefits:**
- Organizes data for better user experience.
- Enables efficient filtering based on sorted criteria.
**Choosing the right method:**
- For large datasets, cursor-based pagination is generally preferred due to its efficiency.
- If dealing with smaller datasets or prioritizing simplicity, limit-offset might be suitable.
- Consider user needs and the size of your data when making the choice.
## **Key Points:**
- Prisma generates type-safe queries based on your schema, ensuring correctness.
- Queries are automatically optimized for performance.
- Nested reads reduce the number of database round trips.
- Relation filters allow for precise data retrieval.
## **Remember:**
- Always import the Prisma Client in your code: `const { PrismaClient } = require('@prisma/client');`
- Instantiate the client: `const prisma = new PrismaClient();`
- Close the client after use: `await prisma.$disconnect();`