Home Web Front-end JS Tutorial Prisma ORM: Start to End With Project using JS

Prisma ORM: Start to End With Project using JS

Jan 16, 2025 pm 06:43 PM

Prisma ORM: Start to End With Project using JS

What is Prisma?

Prisma: Next-Generation ORM for Node.js and TypeScript

ORM: Object Relation Mapping is a way to communicate with databases using OOP languages, without the need to write complex queries.

  • Prisma aims to make databases easy for developers.
  • It provides type safety, an intuitive API, and boosts developer productivity.
  • Focuses on the developer experience.

Key Components

  • Prisma Schema: The single source of truth for your database schema. Defines models and their relations.
  • Prisma Client: Auto-generated query builder tailored to your schema. Provides type-safe access to your database.
  • Prisma Migrate: Tool for managing database schema migrations.

Why Prisma?

  1. Simplifying database interactions: Prisma ORM provides intuitive queries and schema migration.
  2. Enhancing code quality: Prisma ORM generates type-safe queries and integrates with popular IDEs.
  3. Supporting multiple databases: Prisma ORM makes it easier to adapt and grow applications. (e.g., MongoDB, MySQL, MariaDB, PostgreSQL, Microsoft SQL, etc.)
  4. Mitigating problems of traditional ORMs: Prisma ORM addresses issues like bloated model instances and unpredictable queries.

Project Setup

1. Project Setup

Create a new project directory

mkdir prisma-example
cd prisma-example
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login

Initialize a Node.js project

npm init -y
Copy after login
Copy after login
Copy after login
Copy after login

Install Prisma CLI

npm install prisma dotenv express --save-dev
Copy after login
Copy after login
Copy after login
Copy after login

Install the Prisma Client

npm install @prisma/client --save-dev
Copy after login
Copy after login
Copy after login
Copy after login

This installs the Prisma Client for your database.

2. Initialize Prisma

npx prisma init
Copy after login
Copy after login
Copy after login
Copy after login

This creates a prisma directory containing:

  • schema.prisma: Your Prisma schema file.
  • .env: For your database connection string.

3. Configure the Database Connection

Choose a Database

The video likely uses PostgreSQL, but you can adapt this to MySQL, SQLite, or others. For this example, we'll use PostgreSQL.

Set the DATABASE_URL

In your .env file, add the connection string. Example for PostgreSQL:

DATABASE_URL="postgresql://your_user:your_password@localhost:5432/your_database"
Copy after login
Copy after login
Copy after login
Copy after login

Replace your_user, your_password, and your_database with your actual credentials. If you don't have a local PostgreSQL server, you'll need to install and configure one.

4. Define the Data Models (schema.prisma)

Replace the contents of prisma/schema.prisma with the following:

mkdir prisma-example
cd prisma-example
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login

5. Generate the Prisma Client

npm init -y
Copy after login
Copy after login
Copy after login
Copy after login

This generates the type-safe Prisma Client in node_modules/@prisma/client.

6. Create a Migration

npm install prisma dotenv express --save-dev
Copy after login
Copy after login
Copy after login
Copy after login

This creates a new migration file in the prisma/migrations directory and applies it to your database, creating the tables. The --name init gives the migration a descriptive name.

7. Creating a Separate File for Prisma Setup

Create a db.config.js file in the root directory and add the following code:

npm install @prisma/client --save-dev
Copy after login
Copy after login
Copy after login
Copy after login

This will create a new instance of PrismaClient and export it so that it can be used in other files. The log: ['query'] option will log all queries to the console.

8. Creating a Basic Express API to Understand Prisma Working

1. Controller

Create a controllers.js file in the root of the project. The following is the code for CRUD operations in the controllers.js file:

npx prisma init
Copy after login
Copy after login
Copy after login
Copy after login

2. Routes

Create a routes.js file in the root of the project. The following is the code for CRUD operations in the routes.js file:

DATABASE_URL="postgresql://your_user:your_password@localhost:5432/your_database"
Copy after login
Copy after login
Copy after login
Copy after login

3. Server

Create a server.js file in the root of the project. The following is the code for CRUD operations in the server.js file:

generator client {
    provider = "prisma-client-js"
}

datasource db {
    provider = "postgresql" // Or "mysql", "sqlite", etc.
    url      = env("DATABASE_URL")
}

model Post {
    id        String   @id @default(uuid())
    title     String
    content   String?
    createdAt DateTime @default(now())
    author    User     @relation(fields: [user_id], references: [id])
    user_id   Int
}

model User {
    id    Int     @id @default(autoincrement())
    email String  @unique
    name  String?
    posts Post[]
}
Copy after login
Copy after login
Copy after login

9. Run the Script

npx prisma generate
Copy after login
Copy after login
Copy after login

This will execute the script, creating a user and a post in your database, then updating the user and deleting the post.

You can use Postman to test the API with the following routes:

  • POST: http://localhost:5000/api/users
  • GET: http://localhost:5000/api/users
  • GET: http://localhost:5000/api/users/1
  • PUT: http://localhost:5000/api/users/1
  • DELETE: http://localhost:5000/api/users/1

Set the body in Postman for the POST request as JSON with the following data:

npx prisma migrate dev --name init
Copy after login
Copy after login
Copy after login

Key Points to Consider for Prisma Syntax

  • findUnique/findFirst - to get a single record, does not return an array.
  • findMany - to get multiple records, returns an array.
  • include - to include the related data.
  • select - to select specific fields.
  • You can only use one of the attributes, either select or include.

Examples of Prisma Syntax

import { PrismaClient } from "@prisma/client";

const prisma = new PrismaClient({
    log: ["query"],
});

export default prisma;
Copy after login
Copy after login
Copy after login

More on Prisma Aggregations, Filtering, Ordering, and Relations

1. Aggregation Functions in Prisma

Prisma provides several aggregation functions that allow you to perform calculations on sets of data directly within your database queries. These functions are useful for summarizing data and gaining insights without having to fetch large amounts of data to your application.

Common Aggregation Functions

  • _count: Counts the number of records that match the given criteria.
  • _avg: Calculates the average of a numeric field.
  • _sum: Calculates the sum of a numeric field.
  • _min: Finds the minimum value of a field.
  • _max: Finds the maximum value of a field.

Examples of Aggregation

Let's assume we have the following Product model:

mkdir prisma-example
cd prisma-example
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login

Counting the Number of Products in Each Category

npm init -y
Copy after login
Copy after login
Copy after login
Copy after login

Calculating the Average Price of All Products

npm install prisma dotenv express --save-dev
Copy after login
Copy after login
Copy after login
Copy after login

Finding the Minimum and Maximum Price of Products in a Specific Category

npm install @prisma/client --save-dev
Copy after login
Copy after login
Copy after login
Copy after login

Sum of Prices for Products Created in the Last Week

npx prisma init
Copy after login
Copy after login
Copy after login
Copy after login

2. Filtering in Prisma

Prisma offers a rich set of filtering options that allow you to precisely query your database. Here's a comprehensive overview with examples:

Basic Filtering

  • equals (Default): Checks for exact equality.

    DATABASE_URL="postgresql://your_user:your_password@localhost:5432/your_database"
    
    Copy after login
    Copy after login
    Copy after login
    Copy after login
  • not: Negates a condition.

    generator client {
        provider = "prisma-client-js"
    }
    
    datasource db {
        provider = "postgresql" // Or "mysql", "sqlite", etc.
        url      = env("DATABASE_URL")
    }
    
    model Post {
        id        String   @id @default(uuid())
        title     String
        content   String?
        createdAt DateTime @default(now())
        author    User     @relation(fields: [user_id], references: [id])
        user_id   Int
    }
    
    model User {
        id    Int     @id @default(autoincrement())
        email String  @unique
        name  String?
        posts Post[]
    }
    
    Copy after login
    Copy after login
    Copy after login

Comparison Operators

  • gt (Greater Than), gte (Greater Than or Equal To), lt (Less Than), lte (Less Than or Equal To): Used for numeric and date/time comparisons.

    npx prisma generate
    
    Copy after login
    Copy after login
    Copy after login

String Filters

  • contains: Checks if a string contains a substring.

    npx prisma migrate dev --name init
    
    Copy after login
    Copy after login
    Copy after login
  • startsWith: Checks if a string starts with a prefix.

    import { PrismaClient } from "@prisma/client";
    
    const prisma = new PrismaClient({
        log: ["query"],
    });
    
    export default prisma;
    
    Copy after login
    Copy after login
    Copy after login
  • endsWith: Checks if a string ends with a suffix.

    import prisma from "./db.config.js";
    
    // create user
    export const createUser = async (req, res) => {
        const { name, email } = req.body;
    
        const existing_user = await prisma.user.findUnique({
            where: {
                email,
            },
        });
    
        if (existing_user) {
            return res.status(400).json({ message: "User already exists" });
        }
    
        const user = await prisma.user.create({
            data: {
                email,
                name,
            },
        });
    
        return res.status(201).json(user);
    };
    
    // create post
    export const createPost = async (req, res) => {
        const { title, content, user_id } = req.body;
    
        const post = await prisma.post.create({
            data: {
                title,
                content,
                user_id,
            },
        });
    
        return res.status(201).json(post);
    };
    
    // get all users
    export const getUsers = async (req, res) => {
        const users = await prisma.user.findMany({
            include: {
                posts: true,
            },
        });
    
        return res.status(200).json(users);
    };
    
    // read specific user by id
    export const getUserById = async (req, res) => {
        const { id } = req.params;
    
        const user = await prisma.user.findUnique({
            where: {
                id: parseInt(id),
            },
            include: {
                posts: true,
            },
        });
    
        if (!user) {
            return res.status(404).json({ message: "User not found" });
        }
    
        return res.status(200).json(user);
    };
    
    // update user
    export const updateUser = async (req, res) => {
        const { id } = req.params;
        const { name, email } = req.body;
    
        const user = await prisma.user.update({
            where: {
                id: parseInt(id),
            },
            data: {
                name,
                email,
            },
        });
    
        return res.status(200).json(user);
    };
    
    // delete user
    export const deleteUser = async (req, res) => {
        const { id } = req.params;
    
        const user = await prisma.user.delete({
            where: {
                id: parseInt(id),
            },
        });
    
        return res.status(200).json(user);
    };
    
    // create similar for post
    
    Copy after login
  • mode: insensitive: Performs case-insensitive searches.

    import express from "express";
    import {
        createUser,
        createPost,
        getUsers,
        getUserById,
        updateUser,
        deleteUser,
    } from "./controllers.js";
    
    const router = express.Router();
    
    router.post("/users", createUser);
    router.get("/users", getUsers);
    router.get("/users/:id", getUserById);
    router.put("/users/:id", updateUser);
    router.delete("/users/:id", deleteUser);
    // create similar for post
    router.post("/posts", createPost);
    // router.get('/posts', getPosts);
    // router.get('/posts/:id', getPostById);
    // router.put('/posts/:id', updatePost);
    // router.delete('/posts/:id', deletePost);
    
    export default router;
    
    Copy after login

List Filters

  • in: Checks if a value is present in a list.

    import express from "express";
    import dotenv from "dotenv";
    import router from "./routes.js";
    
    dotenv.config();
    
    const app = express();
    
    app.use(express.json());
    app.use("/api", router);
    
    const PORT = process.env.PORT || 5000;
    
    app.listen(PORT, () => {
        console.log(`Server running on port ${PORT}`);
    });
    
    Copy after login
  • notIn: Checks if a value is not present in a list.

    node index.js
    
    Copy after login

Logical Operators

  • AND: Combines multiple conditions with a logical AND.

    {
        "name": "John Doe",
        "email": "sample@example.com"
    }
    
    Copy after login
  • OR: Combines multiple conditions with a logical OR.

    // get all posts of a user with id
    const user = await prisma.user.findUnique({
        where: {
            id: parseInt(id),
        },
        include: {
            posts: true,
        },
    });
    
    // select specific fields of user with post details
    const user = await prisma.user.findUnique({
        where: {
            id: parseInt(id),
        },
        select: {
            name: true,
            posts: {
                select: {
                    title: true,
                    content: true,
                },
            },
        },
    });
    
    // get all users name with their posts count (Aggregation)
    const req_data = await prisma.user.findMany({
        select: {
            id: true,
            name: true,
            _count: {
                select: {
                    post: true,
                },
            },
        },
    });
    
    Copy after login
  • NOT: Negates a group of conditions.

    model Product {
        id        Int      @id @default(autoincrement())
        name      String
        price     Float
        category  String
        createdAt DateTime @default(now())
    }
    
    Copy after login

Nested Filters (Filtering on Relations)

You can filter based on related models.

mkdir prisma-example
cd prisma-example
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login

Filtering on Optional Relations

npm init -y
Copy after login
Copy after login
Copy after login
Copy after login

Combining Filters

You can combine these operators for complex filtering logic.

npm install prisma dotenv express --save-dev
Copy after login
Copy after login
Copy after login
Copy after login

These examples cover the most common filtering scenarios in Prisma. By combining these operators and nested filters, you can create very precise queries to retrieve the exact data you need. Remember to consult the official Prisma documentation for the most up-to-date and detailed information.

Order Records in Prisma

Prisma's orderBy option allows you to sort the results of your queries. Here are some examples demonstrating its usage:

Basic Ordering

  • Ascending Order (Default):

    npm install @prisma/client --save-dev
    
    Copy after login
    Copy after login
    Copy after login
    Copy after login
  • Descending Order:

    npx prisma init
    
    Copy after login
    Copy after login
    Copy after login
    Copy after login

Ordering by Multiple Fields

You can specify multiple fields to order by, with different directions for each. Prisma will first sort by the first field, then by the second field within groups of identical values in the first field, and so on.

DATABASE_URL="postgresql://your_user:your_password@localhost:5432/your_database"
Copy after login
Copy after login
Copy after login
Copy after login

In this example, posts will be primarily sorted by the author's name in ascending order. If multiple posts have the same author, they will then be sorted by their titles in descending order.

Ordering by Nested Fields (Relations)

As shown in the previous example, you can order by fields on related models.

generator client {
    provider = "prisma-client-js"
}

datasource db {
    provider = "postgresql" // Or "mysql", "sqlite", etc.
    url      = env("DATABASE_URL")
}

model Post {
    id        String   @id @default(uuid())
    title     String
    content   String?
    createdAt DateTime @default(now())
    author    User     @relation(fields: [user_id], references: [id])
    user_id   Int
}

model User {
    id    Int     @id @default(autoincrement())
    email String  @unique
    name  String?
    posts Post[]
}
Copy after login
Copy after login
Copy after login

This will order posts based on the email address of their authors.

Ordering by Date/Time Fields

You can order by date and time fields as well.

npx prisma generate
Copy after login
Copy after login
Copy after login

Ordering by a Different Field than the Filtering Field

You can filter by one field and order by another. For example, you might want to find all users with a name containing "test" but order them by their email address:

npx prisma migrate dev --name init
Copy after login
Copy after login
Copy after login

Using nulls Option

You can control how null values are handled in the sorting. The nulls option can be set to either first or last.

import { PrismaClient } from "@prisma/client";

const prisma = new PrismaClient({
    log: ["query"],
});

export default prisma;
Copy after login
Copy after login
Copy after login

By default, null values are placed last when sorting in ascending order and first when sorting in descending order. The nulls option allows you to override this default behavior.

Relation Functions in Prisma

Prisma excels at handling database relationships elegantly. Here are the key aspects:

  • Defining Relationships in the Schema: You define relationships between models directly in your schema.prisma file using the @relation attribute.

  • Types of Relationships: Prisma supports:

    • One-to-One: One record in model A is related to exactly one record in model B.
    • One-to-Many: One record in model A is related to multiple records in model B.
    • Many-to-Many: Multiple records in model A are related to multiple records in model B (requires a join table).

Examples of Relations

Let's use the User and Post models from the previous examples:

mkdir prisma-example
cd prisma-example
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login

Hope this helps you to understand the Prisma ORM in a better way.
Feel free to give your feedback and suggestions.

Thanks for reading! ?

The above is the detailed content of Prisma ORM: Start to End With Project using JS. For more information, please follow other related articles on the PHP Chinese website!

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Roblox: Bubble Gum Simulator Infinity - How To Get And Use Royal Keys
3 weeks ago By 尊渡假赌尊渡假赌尊渡假赌
Nordhold: Fusion System, Explained
4 weeks ago By 尊渡假赌尊渡假赌尊渡假赌
Mandragora: Whispers Of The Witch Tree - How To Unlock The Grappling Hook
3 weeks ago By 尊渡假赌尊渡假赌尊渡假赌

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

Hot Topics

Java Tutorial
1670
14
PHP Tutorial
1274
29
C# Tutorial
1256
24
Python vs. JavaScript: The Learning Curve and Ease of Use Python vs. JavaScript: The Learning Curve and Ease of Use Apr 16, 2025 am 12:12 AM

Python is more suitable for beginners, with a smooth learning curve and concise syntax; JavaScript is suitable for front-end development, with a steep learning curve and flexible syntax. 1. Python syntax is intuitive and suitable for data science and back-end development. 2. JavaScript is flexible and widely used in front-end and server-side programming.

From C/C   to JavaScript: How It All Works From C/C to JavaScript: How It All Works Apr 14, 2025 am 12:05 AM

The shift from C/C to JavaScript requires adapting to dynamic typing, garbage collection and asynchronous programming. 1) C/C is a statically typed language that requires manual memory management, while JavaScript is dynamically typed and garbage collection is automatically processed. 2) C/C needs to be compiled into machine code, while JavaScript is an interpreted language. 3) JavaScript introduces concepts such as closures, prototype chains and Promise, which enhances flexibility and asynchronous programming capabilities.

JavaScript and the Web: Core Functionality and Use Cases JavaScript and the Web: Core Functionality and Use Cases Apr 18, 2025 am 12:19 AM

The main uses of JavaScript in web development include client interaction, form verification and asynchronous communication. 1) Dynamic content update and user interaction through DOM operations; 2) Client verification is carried out before the user submits data to improve the user experience; 3) Refreshless communication with the server is achieved through AJAX technology.

JavaScript in Action: Real-World Examples and Projects JavaScript in Action: Real-World Examples and Projects Apr 19, 2025 am 12:13 AM

JavaScript's application in the real world includes front-end and back-end development. 1) Display front-end applications by building a TODO list application, involving DOM operations and event processing. 2) Build RESTfulAPI through Node.js and Express to demonstrate back-end applications.

Understanding the JavaScript Engine: Implementation Details Understanding the JavaScript Engine: Implementation Details Apr 17, 2025 am 12:05 AM

Understanding how JavaScript engine works internally is important to developers because it helps write more efficient code and understand performance bottlenecks and optimization strategies. 1) The engine's workflow includes three stages: parsing, compiling and execution; 2) During the execution process, the engine will perform dynamic optimization, such as inline cache and hidden classes; 3) Best practices include avoiding global variables, optimizing loops, using const and lets, and avoiding excessive use of closures.

Python vs. JavaScript: Community, Libraries, and Resources Python vs. JavaScript: Community, Libraries, and Resources Apr 15, 2025 am 12:16 AM

Python and JavaScript have their own advantages and disadvantages in terms of community, libraries and resources. 1) The Python community is friendly and suitable for beginners, but the front-end development resources are not as rich as JavaScript. 2) Python is powerful in data science and machine learning libraries, while JavaScript is better in front-end development libraries and frameworks. 3) Both have rich learning resources, but Python is suitable for starting with official documents, while JavaScript is better with MDNWebDocs. The choice should be based on project needs and personal interests.

Python vs. JavaScript: Development Environments and Tools Python vs. JavaScript: Development Environments and Tools Apr 26, 2025 am 12:09 AM

Both Python and JavaScript's choices in development environments are important. 1) Python's development environment includes PyCharm, JupyterNotebook and Anaconda, which are suitable for data science and rapid prototyping. 2) The development environment of JavaScript includes Node.js, VSCode and Webpack, which are suitable for front-end and back-end development. Choosing the right tools according to project needs can improve development efficiency and project success rate.

The Role of C/C   in JavaScript Interpreters and Compilers The Role of C/C in JavaScript Interpreters and Compilers Apr 20, 2025 am 12:01 AM

C and C play a vital role in the JavaScript engine, mainly used to implement interpreters and JIT compilers. 1) C is used to parse JavaScript source code and generate an abstract syntax tree. 2) C is responsible for generating and executing bytecode. 3) C implements the JIT compiler, optimizes and compiles hot-spot code at runtime, and significantly improves the execution efficiency of JavaScript.

See all articles