Главная / Статьи / Настройка Prisma 7 в проекте Next.js 16 на TypeScript

Настройка Prisma 7 в проекте Next.js 16 на TypeScript

Узнайте, как установить, настроить и мигрировать Prisma 7 с PostgreSQL в приложении Next.js 16, а затем создайте одиночный клиент для предотвращения утечек соединений.

991 слов

В этом руководстве показано, как настроить Prisma 7 в приложении Next.js 16, которое взаимодействует с PostgreSQL, используя TypeScript и pnpm в качестве менеджера пакетов.

Шаг 1: Добавление пакетов Prisma

pnpm add prisma @prisma/client @prisma/adapter-pg
  • prisma — инструмент командной строки, который будет использоваться для выполнения миграций, генерации клиентской библиотеки и управления схемой.
  • @prisma/client — генерируемая клиентская библиотека, к которой будет напрямую обращаться код приложения.
  • @prisma/adapter-pg — адаптер драйвера PostgreSQL, введенный Prisma 7 для подключения к Postgres.

После установки этих трех пакетов вы готовы к настройке Prisma.

Шаг 2: Настройка Prisma

pnpm dlx prisma init

Запуск этого скрипта создает базовые файлы и папки, необходимые для начала работы.

prisma.config.ts
prisma/
└── schema.prisma

Понимание файла prisma.config.ts

В этом файле хранятся настройки, необходимые Prisma для работы, включая способ подключения к базе данных и поведение генератора клиента.

import "dotenv/config";
import { defineConfig } from "prisma/config";

export default defineConfig({
    schema: "prisma/schema.prisma",
    migrations: {
        path: "prisma/migrations",
    },
    datasource: {
        url: process.env["DATABASE_URL"],
    },
});

Понимание файла schema.prisma

Любая таблица, которую вы планируете хранить в PostgreSQL, со временем появится здесь в виде определения модели.

generator client {
  provider = "prisma-client"
  output   = "../lib/generated/prisma"
}

datasource db {
  provider = "postgresql"
}

// models that You want to create

Шаг 3: Настройка Prisma под вашу базу данных

Прежде чем Prisma сможет взаимодействовать с базой данных, ему необходим строка подключения. Ее можно получить у хостингового провайдера, такого как Neon, или запустив инстанцу Postgres локально с помощью Docker.

DATABASE_URL="postgresql://username:password@localhost:5432/my_database"

Как только эта переменная среды установлена, Prisma может получить доступ к вашей базе данных.

Шаг 4: Определение начальной модели

Клиент Prisma нельзя сгенерировать, пока в схеме не будет хотя бы одной модели.

Поскольку на данный момент база данных пуста, добавьте минимальную временную модель, чтобы у Prisma было что обрабатывать.

model Test {
  id Int @id @default(autoincrement())
}

Цель здесь — не создание значимой таблицы, а просто предоставление генератору валидной схемы для работы.

Шаг 5: Применение первой миграции

Далее преобразуйте эту схему в реальные таблицы базы данных, выполнив миграцию.

pnpm dlx prisma migrate dev

Эта одна команда автоматически обрабатывает несколько задач:

  • Она генерирует новый файл миграции.
  • Она применяет эту миграцию к настроенной базе данных.
  • Она поддерживает синхронизацию структуры активной базы данных с тем, что указано в schema.prisma.

После успешного завершения таблица Test появится в вашей базе данных.

Шаг 6: Создание клиента Prisma

Одним из наиболее заметных изменений в Prisma 7 является то, что клиент больше не генерируется автоматически.

Теперь вам необходимо явно запускать процесс генерации.

pnpm dlx prisma generate dev

После завершения этого процесса Prisma создает полностью типизированный клиент, адаптированный под вашу схему.

Этот клиент предоставляет все методы, необходимые для запроса и изменения данных.

generated/
└── prisma/

Каждая модель, определенная в вашей схеме, теперь представлена как отдельный типизированный API на TypeScript.

Шаг 7: Создание одиночного экземпляра клиента Prisma

Вместо создания нового экземпляра Prisma Client при каждом запросе лучшей практикой является использование одного общего экземпляра во всем приложении.

File: lib/prisma.ts
import { PrismaPg } from "@prisma/adapter-pg";
import { PrismaClient } from "./generated/prisma/client";

const globalForPrisma = globalThis as unknown as {
    prisma: PrismaClient | undefined;
};

function createPrismaClient() {
    const url = process.env.DATABASE_URL;
    if (!url) {
        throw new Error("DATABASE_URL is not set");
    }

    const adapter = new PrismaPg({ connectionString: url });
    return new PrismaClient({ adapter });
}

export const prisma = globalForPrisma.prisma ?? createPrismaClient();

if (process.env.NODE_ENV !== "production") {
    globalForPrisma.prisma = prisma;
}

Почему здесь важен одиночный экземпляр

Во время разработки Next.js постоянно перезагружает модули.

Если при каждой перезагрузке создается новый экземпляр PrismaClient, это приводит к открытию гораздо большего количества соединений с базой данных, чем предусмотрено.

Если это не исправить, со временем появится ошибка примерно такого содержания:

Too many database connections

Использование паттерна Singleton гарантирует, что единственный экземпляр Prisma Client будет существовать на протяжении всего срока жизни приложения.

Именно этот подход рекомендуется самим Prisma для проектов Next.js.

Шаг 8: Использовать клиент во всем приложении

После создания общего экземпляра клиента его можно импортировать из любой части проекта.

import { prisma } from "@/lib/prisma";

Теперь любой серверный компонент, API-маршрут или серверная операция имеют прямой доступ к вашей базе данных.

Для получения более подробной информации об этой настройке ознакомьтесь с официальной документацией Prisma по интеграции с Next.js, доступной по адресу prisma.io/docs/guides/nextjs.

Связанная литература

  • Настройка Prisma 7 с PostgreSQL в проекте на TypeScript и Node.js — Устранение распространённых ошибок настройки Prisma 7 в TypeScript, от проблем с строковыми или неопределёнными URL до ошибок rootDir, а также подключение PostgreSQL с использованием адаптера драйвера pg.
  • Вход в аккаунт через Google с Auth.js и Prisma: объединение руководств Next.js — Слияние руководств по Prisma и Auth.js для Next.js в одно рабочее приложение с возможностью входа через Google, сохранением данных пользователей и постов, связанных с сессией, включая исправления, которые пропущены в документации.
  • Разделение слоев домена, данных и пользовательского интерфейса в кодбазе Next.js App Router — пример из Pokédex, демонстрирующий, как разделить приложение Next.js App Router на слои домена, данных и представления с использованием Prisma, Zod, аутентификации через куки и кэширования.
  • Prisma без Prisma Client: типобезопасные запросы Kysely в Next.js — узнайте, как использовать Prisma для работы со схемами, генерировать типы Kysely с помощью prisma-kysely, выбирать диалект Neon или pg и выполнять типобезопасные запросы из серверного кода Next.js.