Prisma - установка в проект

Установка поддержки Prisma в NestJS-проекте выполняется очень просто - при помощи двух команд.

Первая - устанавливает клиентскую часть Prisma:

$ npm i @prisma/client

... вторая команда - устанавливает cli-часть Prisma:

$ npm i -D prisma

После этого - нужно запустить команду для инициализации Prisma в текущем проекте:

$ npx prisma init

В результате в корне проекта будет создана папка prisma, внутри которой будет находиться файл schema.prisma для настройки подключения Prisma к базе данных (и не только).

Содержимое файла schema.prisma очень простое:

// This is your Prisma schema file,
// learn more about it in the docs: https://pris.ly/d/prisma-schema

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

datasource db {
  provider = "postgresql"
  url      = env("DATABASE_URL")
}

Наиболее существенные здесь две вещи - это драйвер postgresql для подключения к базе данных PostgreSQL (по умолчанию используется подключение именно к PostgreSQL). Если база данных другая - MySQL и тп - то меняем на нужный драйвер.

Вторая - это строка url, которая используется как настроечный файл для подключения к базе данных. Эта строка (в виде переменной DATABASE_URL) хранится в файле .env, который также автоматически создается Prisma при инициализации.

Если посмотреть на содержимое файла .env, то он будет таким:

# Environment variables declared in this file are automatically made available to Prisma.
# See the documentation for more detail: https://pris.ly/d/prisma-schema#accessing-environment-variables-from-the-schema

# Prisma supports the native connection string format for PostgreSQL, MySQL, SQLite, SQL Server, MongoDB (Preview) and CockroachDB (Preview).
# See the documentation for all the connection string options: https://pris.ly/d/connection-strings

DATABASE_URL="postgresql://johndoe:randompassword@localhost:5432/mydb?schema=public"

То есть - в одной строке - выполняется полная настройка подключения к существующей базе данных. В моем (учебном) случае это выглядит таким образом:

DATABASE_URL="postgresql://postgres:123@localhost:5432/udemy_medium_clone?schema=public"

То есть - postgres - имя пользователя базы данных; 123 - пароль пользователя базы данных; udemy_medium_clone - имя базы данных.

Откуда я взял \ узнал эти данные? Просто я заранее создал учебную базу данных в PostgreSQL, у себя локально (в моем случае):

postgres=# CREATE DATABASE udemy_medium_clone;
CREATE DATABASE
postgres=# \c udemy_medium_clone 
You are now connected to database "udemy_medium_clone" as user "postgres".
udemy_medium_clone=# \conninfo
You are connected to database "udemy_medium_clone" as user "postgres" via socket in "/var/run/postgresql" at port "5432".

localhost:5432 - я оставил по умолчанию, так как - у меня PostgreSQL также по умолчанию слушает этот порт.

Не забываем добавить файл .env в .gitignore, чтобы данные не засветились на удаленном репозитории - и все, основная настройка Prisma завершена.

Prisma - миграция баз данных

В моем случае - база данных udemy_medium_clone - чистая, в ней пока нет никаких таблиц. Это можно исправить двумя способами.

Первый - создать таблицу в базе данных силами самого SQL и затем выполнить преобразование таблицы в модель данных (Prisma schema) в проекте - командой:

$ prisma db pull

Второй - наоборот, создать модель данных Prisma в проекте и затем мигрировать ее в PostgreSQL, что автоматически приведет к созданию такой таблицы в базе данных.

Давайте поступим по второму варианту. Создадим в файле schema.prisma модель данных пользователя будущего приложения:

// This is your Prisma schema file,
// learn more about it in the docs: https://pris.ly/d/prisma-schema

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

datasource db {
  provider = "postgresql"
  url      = env("DATABASE_URL")
}

model Users {
  id       Int     @id @default(autoincrement())
  email    String  @unique @db.VarChar(255)
  bio      String?
  image    String? @db.VarChar(500)
  password String  @unique @db.VarChar(255)
  username String  @unique @db.VarChar(255)

  @@map("users")
}

Кстати - под Visual Studio Code и WebStorm - есть специальные плагины для подсветки синтаксиса и форматирования файлов с расширением *.prisma:

И все - можно выполнить миграцию в базу данных командой:

$ npx prisma migrate dev --name users

... где --name users - это имя конкретной миграции, чтобы можно было локально увидеть и отследить эту операцию. По выполнении Prisma выведет в консоль отчет об успешной операции:

Environment variables loaded from .env
Prisma schema loaded from prisma/schema.prisma
Datasource "db": PostgreSQL database "udemy_medium_clone", schema "public" at "localhost:5432"

Applying migration `20220223160632_users`

The following migration(s) have been created and applied from new schema changes:

migrations/
  └─ 20220223160632_users/
    └─ migration.sql

Your database is now in sync with your schema.

✔ Generated Prisma Client (3.10.0 | library) to ./node_modules/@prisma/client in 75ms

Как видно из отчета, Prisma создала подпапку migrations, внутри которой будут находиться - папки с детальной информацией - по каждой конкретной миграции.

В моем случае - это будет папка 20220223160632_users (помним о ключе --name users) и внутри этой папки - любопытный файлик migration.sql.

Если открыть этот файлик, то увидим не что иное, как набор обычных SQL-команд по созданию таблицы базы данных:

-- CreateTable
CREATE TABLE "users" (
    "id" SERIAL NOT NULL,
    "email" VARCHAR(255) NOT NULL,
    "bio" TEXT,
    "image" VARCHAR(500),
    "password" VARCHAR(255) NOT NULL,
    "username" VARCHAR(255) NOT NULL,

    CONSTRAINT "users_pkey" PRIMARY KEY ("id")
);

-- CreateIndex
CREATE UNIQUE INDEX "users_email_key" ON "users"("email");

-- CreateIndex
CREATE UNIQUE INDEX "users_password_key" ON "users"("password");

-- CreateIndex
CREATE UNIQUE INDEX "users_username_key" ON "users"("username");

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

Думаю, стоит обратить внимание на тот момент, что созданный файл миграции - нужно проверять всегда, на предмет возможных косяков при его генерации. Кривая миграция может уничтожить терабайт данных, а бэкап при этом - не успел создасться. На что стоит обратить внимание - это правильность создания индексов и foreign keys. И так как в данном скромном мануале используется PostgreSQL, то не лишним будет - указать ссылку на оф документацию по этой БД.

И так, а давайте проверим, так ли это на самом деле - что таблица была успешно создана в базе данных? Легко!

udemy_medium_clone=# \d
                 List of relations
 Schema |        Name        |   Type   |  Owner   
--------+--------------------+----------+----------
 public | _prisma_migrations | table    | postgres
 public | users              | table    | postgres
 public | users_id_seq       | sequence | postgres
(3 rows)

... правда - таблица users была создана. А давайте посмотрим - что из себя представляет эта таблица users:

udemy_medium_clone=# \d users
                                     Table "public.users"
  Column  |          Type          | Collation | Nullable |              Default              
----------+------------------------+-----------+----------+-----------------------------------
 id       | integer                |           | not null | nextval('users_id_seq'::regclass)
 email    | character varying(255) |           | not null | 
 bio      | text                   |           |          | 
 image    | character varying(500) |           |          | 
 password | character varying(255) |           | not null | 
 username | character varying(255) |           | not null | 
Indexes:
    "users_pkey" PRIMARY KEY, btree (id)
    "users_email_key" UNIQUE, btree (email)
    "users_password_key" UNIQUE, btree (password)
    "users_username_key" UNIQUE, btree (username)

... хм, очень похоже на правду - это именно такая таблица, какую я спроектировал в качестве модели в Prisma.

Заключение

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

Конечно же, есть еще один инструмент для работы с базой данных в NestJS - это TypeORM. Но его настройка и подключение для меня настолько сложна, запутанна и трудоемка, что я не стыжусь признаться, что TypeORM я не знаю и особого желания знать - пока не возникло.

Комментарии (0)