Схема¶
В файле schema.prisma мы видим такие строки:
1 2 3 4 5 6 7 8 | |
datasource — источник данных:
provider— название провайдера для доступа к БД:sqlite,postgresql,mysql,sqlserverилиmongodb(по умолчанию —postgresql);url— адрес БД (по умолчанию — значение переменнойDATABASE_URL);shadowDatabaseUrl— адрес "теневой" БД (для БД, предоставляемых облачными провайдерами): используется для миграций для разработки (prisma migrate dev);
generator — генератор клиента на основе схемы:
provider— провайдер генератора (единственным доступным на сегодняшний день провайдером являетсяprisma-client-js);binaryTargets— определяет операционную систему для клиента Prisma. Значением по умолчанию являетсяnative, но иногда это приходится указывать явно, например, при использовании клиента в Docker-контейнере (в этом случае также приходится явно выполнятьprisma generate)
1 2 3 4 5 6 7 8 9 10 | |
Для работы со схемой удобно пользоваться расширением Prisma для VSCode. Соответствующий раздел в файле settings.json должен выглядеть так:
1 2 3 | |
Определим в схеме модели для пользователя (User) и поста (Post):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | |
Вот что мы здесь видим:
id,email,hashetc. — названия полей (колонок таблицы);@mapпривязывает поле схемы (hash) к указанной колонке таблицы (password_hash).@mapне меняет название колонки в БД и поля в генерируемом клиенте. Для MongoDB использование@mapдля@idявляется обязательным:id String @default(auto()) @map("_id") @db.ObjectId;String,Int,DateTimeetc. — типы данных (см. ниже);@db.Uuid— тип данных, специфичный для одной или нескольких БД (в данном случае PostgreSQL);- модификатор
?после названия типа означает, что данное поле является опциональным (необязательным, может иметь значениеNULL); - модификатор
[]после названия типа означает, что значением данного поля является список (массив). Такое поле не может быть опциональным; - префикс
@означает атрибут поля, а префикс@@— атрибут блока (модели, таблицы). Некоторые атрибуты принимают параметры; - атрибут
@idозначает, что данное поле является первичным (основным) ключом таблицы (PRIMARY KEY) (идентификатор модели). Такое поле не может быть опциональным; - атрибут
@defaultприсваивает полю указанное значение по умолчанию (при отсутствии значения поля) (DEFAULT). Дефолтными могут быть статические значения (42,hi) или значения, генерируемые функциямиautoincrement,dbgenerated,cuid,uuidиnow(функции атрибутов; см. ниже); - атрибут
@uniqueозначает, что значение поля должно быть уникальным в пределах таблицы (UNIQUE). Таблица должна иметь хотя бы одно поле@idили@unique; - атрибут
@relationуказывает на существование отношений между таблицами. В данном случае между таблицамиusersиpostsсуществуют отношения один-ко-многим (one-to-many, 1-n) — у одного пользователя может быть несколько постов (FOREIGN KEY/REFERENCES) (об отношениях мы поговорим отдельно); - атрибут
@updatedAtобновляет поле текущими датой и временем при любой модификации записи; у нас имеется перечисление (enum), значения которого используются в качестве значений поляroleмоделиUser(значением по умолчанию являетсяUSER); - атрибут
@@mapпривязывает название модели к названию таблицы в БД.@@mapне меняет название таблицы в БД и модели в генерируемом клиенте.
Типы данных¶
Допустимыми в названиях полей являются следующие символы: [A-Za-z][a-za-z0-9_]*.
String— строка переменной длины (для PostgreSQL — это тип text);Boolean— логическое значение:trueилиfalse(boolean);Int— целое число (integer);BigInt— BigInt (integer);Float— число с плавающей точкой (запятой) (double precision);Decimal(decimal);DateTime— дата и время в формате ISO 8601;Json— объект в формате JSON (jsonb);Bytes(bytea).
Атрибут @db позволяет использовать типы данных, специфичные для одной или нескольких БД.
Атрибуты¶
Кроме упомянутых выше, в схеме можно использовать следующие атрибуты:
@@id— определяет составной (composite) первичный ключ таблицы, например,@@id[title, author](в данном случае соответствующее поле будет называтьсяtitle_author— это можно изменить);@@unique— определяет составное ограничение уникальности (unique constraint) для указанных полей (такие поля не могут быть опциональными), например,@@unique([title, author]);@@index— определяет индекс в БД (INDEX), например,@@index([title, author]);@ignore,@@ignore— используется для обозначения невалидных полей и моделей, соответственно.
Функции атрибутов¶
auto— представляет дефолтные значения, генерируемые БД (только для MongoDB);autoincrement— генерирует последовательные целые числа (SERIALв PostgreSQL, не поддерживается MongoDB);cuid— генерирует глобальный уникальный идентификатор на основе спецификацииcuid;uuid— генерирует глобальный уникальный идентификатор на основе спецификацииUUID;now— возвращает текущую отметку времени (timestamp) (CURRENT_TIMESTAMPв PostgreSQL);dbgenerated— представляет дефолтные значения, которые не могут быть выражены в схеме (например,random()).
Подробнее о схеме можно почитать здесь.
Отношения¶
Атрибут @relation указывает на существование отношений между моделями (таблицами). Он принимает следующие параметры:
name?: string— название отношения;fields?: [field1, field2, ...fieldN]— список полей текущей модели (в нашем случае это[author_id]моделиPost); обратите внимание: само поле определяется отдельно);references: [field1, field2, ...fieldN]— список полей другой модели (стороны отношений) (в нашем случае это[id]моделиUser).
В приведенной выше схеме полями, указывающими на существование отношений между моделями User и Post, являются поля posts и author. Эти поля существуют только на уровне Prisma, в БД они не создаются. Скалярное поле author_id также существует только на уровне Prisma — это внешний ключ (FOREIGN KEY), соединяющий Post с User.
Как известно, существует 3 вида отношений:
- один-к-одному (one-to-one, 1-1);
- один-ко-многим (one-to-many, 1-n);
- многие-ко-многим (many-to-many, m-n).
Атрибут @relation является обязательным только для отношений 1-1 и 1-n.
Предположим, что в нашей схеме имеются такие модели:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | |
Вот что мы здесь видим:
- между моделями
UserиProfileсуществуют отношения 1-1 — у одного пользователя может быть только один профиль; - между моделями
UserиPostсуществуют отношения 1-n — у одного пользователя может быть несколько постов; - между моделями
PostиCategoryсуществуют отношения m-n — один пост может принадлежать к нескольким категориям, в одну категорию может входить несколько постов.
Подробнее об отношениях можно почитать здесь.