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
:
Prisma
... для Visual Studio Code плагин работает отлично, для WebStorm - так себе.
И все - можно выполнить миграцию в базу данных командой:
$ 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 я не знаю и особого желания знать - пока не возникло.