1) Если редактор не видит обновлённые типы после generate
Если слово data подчёркнуто и не показываются новые типы, то нужно с ctrl тыкнуть по функции create(), чтобы редактор подгрузил типы и увидел обновления модели
В datagrip составляем запрос на подключение внутри окна ctrl+alt+shift+s
Project Setup
Первым делом, нужно установить все нужные модули для нашего проекта
Далее настраиваем конфиг ТСки
tsconfig.json
Prisma Setup
Дальше нужно инициализировать призму в проекте, чтобы ей можно было начать пользоваться.
--datasource-provider позволяет выбрать, к какой базе данных мы сейчас будем подключаться
После инициализации будут сгенерированы файлы схемы и .env
Так же нужно установить плагин в наш редактор, который будет подсвечивать синтаксис и форматировать код призмы
Так же в глобальных настройках VSCode можно добавить данную инструкцию, которая будет форматировать код призмы при сохранении
Первым делом, мы можем определить любой для нашего проекта генератор. Их можно найти на npm. Генератор определяет как будет сгенерирован код SQL
В файле .env указываются глобальные переменные, к которым мы можем обращаться внутри проекта. Конкретно нам нужно указать ссылку для подключения к базе данных
postgres - имя пользователя
0000 - пароль от подключения к серверу (нужно вводить при каждом заходе в базу)
@localhost:5432 - хост подключения
/test - имя базы
.env
Basic Prisma Model Setup
Далее создадим базовую модель
id - имя домена (столбца)
Int - тип домена
@id - его обозначение как айдишника
@default - присваиваем значение по умолчанию для данного типа
autoincrement() - автоинкрементирование значения под каждую новую запись
schema.prisma
Prisma Migration Basics
Далее нам нужно инициализировать миграцию. Миграция - это процесс подключения к базе и создания в ней статичной модели (создание таблиц и связей между ними), которую мы описали в призме. Этот процесс обязателен после добавления новых моделей.
migrate - функция, которая осуществляет миграцию
dev - тут мы определяем, что миграция осуществляется в режиме разработчика
--name - этот флаг позволяет задать имя миграции
init - само наше заданное имя миграции
После миграции у нас генерируется лог с именем и кодом sql, который написан на языке той базы, к которой мы подключились
Prisma Client Basics
Функция generate генерирует типы и интерфейсы тех объектов, к которым мы будем обращаться из кода
Тут мы инициализируем призму в проекте
script.ts
Конкретно сейчас мы сможем совершать действия над нашим сервером - например, подключиться к нему, отключиться, получить модель базы
И уже тут представлен код, где мы инициализируем призму, создаём нового пользователя внутри нашей сгенерированной модели, выводим все записи из определённой таблицы, а так же дисконнектимся от базы
Каждый раз, если мы будем менять имя пользователя внутри name: "имя" у нас будет создаваться новый пользователь с инкрементированным идентификатором
Datasources and Generators
Datasources - это источники наших данных. Первым делом указывается провайдер - база данных. Далее идёт ссылка на получение доступа к БД. Сама ссылка находится в глобальном environment пространстве, которая хранит эти глобальные переменные с данными
Generators - генераторы определяют нашу генерацию кода. Их может быть несколько штук: отдельно для определённого поставщика и того же GraphQL
Model Fields
Поля в моделях внутри призмы состоят из четырёх разных частей:
Имя поля, которое мы задаём своё
Тип поля. Внутри него так же можно указать обязательность поля через ? (обязательно ли поле для заполнения или нет)
Атрибуты. Они уже начинаются с @
Мы имеем достаточное количество разных типов данных, чтобы описать нашу базу:
Int - целое число
String - строка
Boolean - булевое значение
Float - строка с плавающей точкой
Decimal - более точное значение, чем float
BigInt - большое целое число
Bytes - очень маленькое значение
DateTime - дата
Json - json-объект
Unsupported("") - любой другой тип, который не поддерживается в призме. Может пригодиться, если мы добавляем существующую базу данных
Так же поддерживается тип данных, который представляет из себя другой объект базы данных
Model Relationships
Модификаторы типов полей:
Тип? - необязательное поле
Объект[] - много объектов
Атрибут uuid() позволяет сгенерировать порядковый id для конкретного поля
Отношения один ко многим
У пользователя может быть много постов. В постах указываем связь по столбцу внутри модели поста и связываем с полем пользователя
Тут представлена ещё одна разновидность отношений 1 ко многим, где у пользователя есть его написанные посты и любимые посты. Тут, чтобы призма поняла, какой столбец с каким связывается, нужно указать наименование конкретной связи.
Отношения многие ко многим
Если нужно будет делать отношение многие ко многим, то нам не нужно будет выстраивать ссылки с отношениями. Тут мы просто указываем массив одних объектов, которые ссылаются на массив других объектов.
При реализации таких отношений призма создаёт отдельную таблицу, которая связывает данные сущности.
Отношения один к одному
У каждого пользователя есть свои уникальные настройки. Чтобы предпочтение было уникальным, нужно указать, что мы ссылаемся на необязательное поле ? и идентификатор в таблице, на которую ссылаемся должен иметь атрибут уникальности @unique
Model Attributes
Атрибуты полей
Если установить для поля атрибут @unique, то это поле будет всегда уникальным
Если для поля updatedAt установить атрибут @updatedAt, то значение всегда будет всегда равно своему значению
Атрибут @default() всегда устанавливает значение по умолчанию. Конкретно если написать @default(now()) для createdAt, то для этого поля всегда будет устанавливаться значение времени на сейчас
Атрибуты блока
Записываются они через @@ и пишутся в самом конце.
Конкретно в приведённом ниже примере мы указали, что не может быть двоих пользователей с одинаковым возрастом и именем через @@unique([]). Так же через атрибут @@index мы добавляем таблицу с индексом для электронной почты
Так же мы можем сделать составной идентификатор для таблицы вместо использования id. Конкретно тут будет создана новая таблица, в которой будет реализован составной идентификатор, указывающий на определённую запись в этой таблице постов
Enums
Объект enum представляет из себя статичный набор данных, которые мы можем положить в качестве значений в поле. То есть положить мы можем в поле только то, что указали в enum. Тип поля определяется как название enum и так же можно присвоить дефолтное значение из этого перечисления
Client Create Operations
Производим небольшие изменения в таблице, чтобы пользователь сам ссылался на свой настройки и чтобы в настройках хранилось только id пользователя
prisma.scheme
Функция deleteMany() удаляет все записи из таблицы выделенной модели.
Функция create() позволяет создать нам нового пользователя. Вложенное в неё свойство create, которое помещается внутри полей других таблиц, позволяет создать новую запись другой таблицы и связать их сразу. Свойство include позволяет вывести вместе с самим объектом, который мы выводим в консоль ещё и данные по связанным с ним объектам.
script.ts
Так же мы имеем свойство select, которое позволяет вывести отдельные части данных моделей.
Можно пользоваться только include или select и только в функции create()
Так же мы можем выводить дополнительные данные по производимым запросам в нашу базу
Функция createMany() позволяет создать сразу несколько пользователей
И тут нам выходит число созданных записей
Client Read Operations
Выполнение операций по поиску клиентов
findQunique() - выполняет поиск по базе данных на основе ключа
Так же так как мы указали в модели @@unique([age, name]), то мы сможем найти по уникальным значениям определённую запись в базе по уникальной сгенерированной записи age_name
Функция findFirst находит первую попавшуюся запись
Функция findMany() найдёт все записи, которые соответствуют условию (возвращает массив)
Свойство distinct позволяет нам выводить только уникальные значения по определённым полям
Так же мы имеем дополнительно три свойства для сортировки наших полученных результатов:
orderBy - сортирует полученные записи по определённому полю в выбранном порядке
свойство take берёт первое определённое количество из полученных записей
skip - пропускает первую запись
Advanced Filtering
Так же мы можем искать значения, которые мы можем передавать в качестве значений-объектов для более продвинутого поиска нужных нам данных
equals будет искать значения равные введённому
not ищет значения не равные введённому
in ищет значения ровно в данном диапазоне, который мы ввели
notIn ищет значения, которые не входят в данный диапазон
lt ищет значения меньше введённого
Дальше идут свойства, которые ищут не полностью всё значение, а только совпадения
contains - ищет поля, где имеющиеся данные схожи с введёнными
endsWith - ищет поля, где данные заканчиваются данной строкой
startsWith - ищет поля, где данные начинаются с данной строки
Дальше идут свойства условий:
AND - ищет значения, которые удовлетворяют всем фильтрам
OR - ищет значения, которые могут удовлетворять одному из фильтров
NOT - ищет значения, которые не совпадают фильтру поиска
Relationship Filtering
Так же мы можем искать значения по связям, которые реализованы в наших моделях
Так же мы имеем свойства для поиска определённых значений внутри связанных полей:
every - ищет значения, где каждая связь имеет определённое значение
none - ищет значения, которые не равны введённым
some - выведет некоторые
Данный пример выведет всех пользователей, так как у всех пользователей нет постов. Так же если написать none, то выйдут опять все пользователи, так как ни у кого нет такого поста с таким именем. Но если вписать some, то ничего не вернётся, так как нигде нет нужного значения
А уже тут мы выводим посты, пользователям которых 27 лет и не 40
Client Update Operations
Так же нам обязательно нужна будет операция для изменения данных. Конкретно мы имеем функции update и updateMany - где первая обновляет одного пользователя, а вторая всех, кого найдёт.
Первым делом мы должны передать условие where, по которому будет искаться пользователь, а уже далее нужно будет ввести новые данные в data.
Важной особенностью является то, что update позволяет менять данные только по идентификатору (уникальному полю), а updateMany по любому
Так же нужно упомянуть, что у нас есть операции increment, decrement, multiply и divide
Connect Existing Relationships
Так же мы имеем возможность подключать к себе уже существующие компоненты, которые мы предопределили заранее
Для начала создадим новый идентификатор настроек пользователя
Мы можем создать новые настройки пользователя через create
Так же мы можем подключить уже существующие настройки через connect
Выводим настройки
Так же мы можем отключиться от внешних полученных данных с использованием свойства disconnect
Так же мы можем произвести connect сразу при создании нового пользователя
Client Delete Operations
Мы имеем два метода: delete и deleteMany
Когда мы используем функцию delete, нам нужно искать определённую запись по уникальному полю (у нас это почта)
Ну и так же мы можем удалить множество пользователей с использованием deleteMany по заданному условию