IlmHamroh
JavaScript Full-stack/27-qism. Ma'lumotlar bazasi chuqur: Postgres, ORM, Mongo, Redis36/65-dars18 daqiqa
Mundarija (32)

Prisma Migrate: migrate dev, deploy, baseline, diff va resolve

Qisqacha: Prisma Migrate'da ikki asosiy buyruq bor. prisma migrate dev — faqat ishlab chiqishda: schema.prisma ni bazaga solishtiradi, yangi SQL migratsiya yozadi va qo'llaydi. prisma migrate deploy — prodakshnda: faqat tayyor fayllarni qo'llaydi, hech narsa yaratmaydi. Mavjud bazani Prisma'ga o'tkazish — baseline: 0_init fayli + migrate resolve --applied 0_init. Kanon o'lchovi: Prisma'ning o'zi bizning sxemadan 15 CHECK, 6 trigger, 8 funksiyaning birortasini ham yoza olmadi — shuning uchun migratsiya manbai SQL fayllar.

Bu darsda

  • migrate dev, migrate deploy, migrate reset, db push qaysi muhitda ishlatilishini ajrata olasiz.
  • Shadow baza nima uchun kerakligini tushunasiz.
  • Mavjud ma'lumotli bazani baseline qilib Prisma Migrate'ga o'tkazasiz.
  • migrate diff bilan Prisma sxemadan qanday SQL yasashini tekshirasiz.
  • --create-only bilan migratsiyani qo'lda to'ldirasiz va migrate resolve bilan holatni tuzatasiz.

Oldin bilishingiz kerak: Migratsiya tushunchasi, Prisma 7: o'rnatish va arxitektura, Prisma: modellar va atributlar, Prisma prodakshnda.

1. Nega bu kerak?

O'tgan darsda migratsiyaning uch qismini ko'rdik: fayl, tartib, holat jadvali. vazifalar loyihasida fayllar bor (sql/001…106), lekin holat jadvali yo'q — biz bazani har safar noldan qurardik. vazifalar-api esa holat 20 dan beri Prisma'dan foydalanadi. Shunday ekan, savol tug'iladi: migratsiyalarni ham Prisma boshqarsinmi?

Ikki qiyinchilik bor:

  1. Baza allaqachon bor. Unda ma'lumot bor. Prisma'ga "bu sxema allaqachon qo'llangan, qaytadan yaratma" deb aytish kerak.
  2. Sxemamiz Prisma'dan boy. CHECK, EXCLUDE, trigger, RLS, view — Prisma sxema tilida yo'q narsalar. Prisma ularni "ko'rmaydi" — va keyingi migratsiyada o'chirib yubormasligi kerak.

O'xshatish: yangi buxgalter kompaniyaga keldi. Kompaniya 5 yildan beri ishlaydi, hisob daftarlari bor. Buxgalter "hammasini noldan boshlaymiz" demaydi. U shunday yozadi: "2026-yil 25-oktabr holatiga qoldiq — shuncha. Bundan keyingi har operatsiya — mening daftarimda". Bu — baseline.

2. Ikki dunyo: dev va deploy

2.1 Buyruqlar xaritasi

Buyruq Qayerda Nima qiladi
migrate dev Faqat lokal Sxema farqidan yangi migratsiya yozadi va qo'llaydi
migrate dev --create-only Faqat lokal Faylni yozadi, lekin qo'llamaydi
migrate deploy Staging, prodakshn, CI Qo'llanmagan fayllarni qo'llaydi, boshqa hech narsa
migrate status Hamma joyda Qaysilari qo'llangan, qaysilari yo'q
migrate resolve Kerak bo'lganda Holat jadvalini qo'lda tuzatish
migrate diff Hamma joyda Ikki sxema orasidagi SQL farqni chiqaradi (bazaga tegmaydi)
migrate reset Faqat lokal Bazani o'chirib, hammasini noldan qo'llaydi
db push Prototip Sxemani bazaga to'g'ridan-to'g'ri, faylsiz

Eng muhim ikki qator — dev va deploy. Ularni aralashtirish — Prisma loyihalarida eng ko'p uchraydigan qimmat xato.

flowchart LR
  A[schema.prisma] --> B[migrate dev]
  B --> C[migrations/ SQL fayli]
  C --> D[Git, review]
  D --> E[migrate deploy]
  E --> F[(Prodakshn baza)]

Diagrammada migrate dev faqat chap tomonda — dasturchining kompyuterida. Prodakshnga faqat Git orqali o'tgan, review qilingan fayl yetib boradi.

2.2 migrate dev ichida nima bo'ladi

migrate dev bir necha qadam qiladi (Prisma hujjati bo'yicha):

  1. Shadow baza yaratadi — vaqtinchalik bo'sh baza.
  2. Unga hamma mavjud migratsiyalarni qo'llaydi — "fayllar bo'yicha sxema qanday bo'lishi kerak?".
  3. Shu natijani asosiy dev bazangiz bilan solishtiradi — drift bormi?
  4. schema.prisma bilan solishtiradi — farqdan yangi migratsiya SQL'ini yozadi.
  5. Uni dev bazaga qo'llaydi va shadow bazani o'chiradi.

Shadow baza (soya baza) — "toza xona": unda migratsiyalar noldan qo'llanib, haqiqiy sxema hisoblanadi. Shuning uchun migrate dev ga bazada CREATE DATABASE huquqi kerak. Managed xizmatlarda (bulutdagi Postgres) bu huquq ko'pincha yo'q — u holda shadowDatabaseUrl bilan alohida baza beriladi (hujjat bo'yicha; biz sinamadik).

Drift topilsa (masalan bazada qo'lda yaratilgan indeks), migrate dev bazani qayta qurishni taklif qiladi — ya'ni ma'lumotni o'chirishni. Lokal bazada bu normal. Prodakshnda esa migrate dev ni hech qachon ishga tushirmaysiz.

Tekshirib ko'ring: Nega migrate deploy shadow baza ishlatmaydi va farq hisoblamaydi?

Javob

Uning vazifasi boshqa: "nima o'zgarishi kerak?" degan qarorni u qilmaydi. Qaror allaqachon fayl ko'rinishida, Git va review'dan o'tgan. deploy faqat holat jadvaliga qarab, qo'llanmagan fayllarni tartib bilan bajaradi. Prodakshnda "aqlli" vosita xavfli — u kutilmagan narsa qilishi mumkin; "itoatkor" vosita oldindan aytib bo'ladigan.

3. Prisma o'zi qanday SQL yozadi: migrate diff

3.1 Bo'sh bazadan bizning sxemaga

migrate diff bazaga tegmaydi — faqat SQL chiqaradi. Kanon undan "agar Prisma sxemani o'zi yaratganda nima bo'lardi?" degan savolga javob olgan:

bash
npx prisma migrate diff --from-empty \
  --to-schema prisma/schema.prisma --script

Natija — 139 qatorli SQL. Boshi (eng yuqoridagi CREATE SCHEMA IF NOT EXISTS "public" qatorini tashladik):

sql
-- CreateEnum
CREATE TYPE "ustuvorlik" AS ENUM ('past', 'orta', 'yuqori');

-- CreateTable
CREATE TABLE "foydalanuvchilar" (
    "id" BIGSERIAL NOT NULL,
    "email" TEXT NOT NULL,
    "ism" TEXT NOT NULL,
    "yaratilgan_vaqt" TIMESTAMPTZ(6) NOT NULL
      DEFAULT CURRENT_TIMESTAMP,
    -- …
    CONSTRAINT "foydalanuvchilar_pkey" PRIMARY KEY ("id")
);

Darhol bitta farq: BIGSERIAL. 26-qismdagi bizning faylda — bigint GENERATED ALWAYS AS IDENTITY (Primary key tanlovi). Prisma sxema tilida bu ikkisi bir xil @default(autoincrement()) bo'lib ko'rinadi, lekin bazada ular farq qiladi (IDENTITY ALWAYS qo'lda id berishni taqiqlaydi).

3.2 Nima yo'q

Kanon Prisma diff'ini bizning SQL fayllarimiz (0_init) bilan obyektma-obyekt sanadi:

Obyekt Prisma diff Bizning SQL
CREATE TABLE 6 6
CREATE INDEX 10 11
FOREIGN KEY 7 7
CHECK 0 15
EXCLUDE 0 3
CREATE FUNCTION 0 8
CREATE TRIGGER 0 6
VIEW / MATERIALIZED VIEW 0 / 0 1 / 1
POLICY (RLS) 0 5
GENERATED ustun 0 7
COMMENT 0 19
CREATE EXTENSION 0 2

Jadvallar, oddiy indekslar va tashqi kalitlar — mos. Qolgan hamma narsa — biz 26–27-qismlarda o'rgangan Postgres'ning kuchli tomonlari — Prisma sxemasida yo'q. Agar sxema manbai schema.prisma bo'lganda, bu 70 dan ortiq obyekt yangi muhitlarda yaratilmasdi: CHECK'siz jadval, trigger'siz tartib, RLS'siz xavfsizlik.

Kanon qarori shundan: sxema manbai — SQL fayllar, schema.prisma — faqat Prisma Client uchun tavsif. Yangi migratsiya migrate dev --create-only bilan yaratiladi, SQL qo'lda tekshiriladi va to'ldiriladi.

Diqqat: Bu cheklov faqat Prisma'ga xos emas. Drizzle-kit pull ko'proq ko'rdi (CHECK, policy, view), lekin EXCLUDE, trigger va funksiyani u ham ko'rmadi (ORM tanlash qo'llanmasi). Boy Postgres sxemasi bor loyihada SQL'ni bilish — shart.

4. Baseline: mavjud bazani Prisma'ga o'tkazish

4.1 0_init fayli

Kanon (holat 36) prisma/migrations/0_init/migration.sql ni yaratdi: sql/ papkadagi namunasiz fayllar (001–014, 101, 103–106) tartib bilan bitta faylga birlashtirildi (551 qator). Namuna fayllari (003-namuna-…, 102-namuna-…) kirmadi — ular ma'lumot, sxema emas. Fayl boshi:

sql
-- 0_init — BASELINE (27-qism holat 36): 26-qism sxemasi
-- (001–014) + 27-qism P bosqichi (101, 103–106), namunasiz.
-- Mavjud bazada: npx prisma migrate resolve --applied 0_init
-- (qayta bajarilmaydi). Yangi bazada: npx prisma migrate deploy.

-- ===== 001-jadvallar.sql =====
CREATE TABLE foydalanuvchilar ( …

Nomdagi 0_ — tartib uchun: Prisma migratsiyalarni nom bo'yicha saralaydi, 0_init har qanday vaqt belgili nomdan (2026…) oldin turadi. Yonida migration_lock.toml — qaysi baza turi uchun yozilgani (provider = "postgresql").

4.2 Yangi baza: deploy

Bo'sh bazada hammasi oddiy (kanon, PostgreSQL 18.6):

bash
npx prisma migrate deploy
text
1 migration found in prisma/migrations
Applying migration `0_init`
The following migration(s) have been applied:
migrations/
  └─ 0_init/
    └─ migration.sql
All migrations have been successfully applied.

Kanon ikki marta o'lchagan: 6 897 ms va 3 228 ms. Keyin bu bazaning pg_dump i qur.sh (SQL fayllardan) qurgan bazaning pg_dump i bilan solishtirildi. Farq — 9 qator, faqat bitta jadval: _prisma_migrations. Ya'ni Prisma orqali qurilgan baza bizning SQL'dan qurilgan baza bilan aynan bir xil, plyus holat jadvali.

4.3 Mavjud baza: P3005 va resolve

Endi namunali, ishlab turgan vazifalar bazasi. Avval holat:

bash
npx prisma migrate status
text
1 migration found in prisma/migrations
Following migration have not yet been applied:
0_init
To apply migrations in development run prisma migrate dev.
To apply migrations in production run prisma migrate deploy.

Prisma _prisma_migrations ni topmadi va 0_init ni "qo'llanmagan" dedi (chiqish kodi 1). Maslahatiga ergashib deploy qilsak:

text
Error: P3005
The database schema is not empty. Read more about how to baseline an existing production database: https://pris.ly/d/migrate-baseline

Tarjimasi: "Baza sxemasi bo'sh emas. Mavjud prodakshn bazasini qanday baseline qilish haqida o'qing". Yaxshi himoya: Prisma ma'lumotli bazaga CREATE TABLE larni ko'r-ko'rona qo'llamadi. Yechim — Prisma'ga "0_init allaqachon shu bazada bor" deyish:

bash
npx prisma migrate resolve --applied 0_init
npx prisma migrate status
npx prisma migrate deploy
text
Migration 0_init marked as applied.
1 migration found in prisma/migrations
Database schema is up to date!
1 migration found in prisma/migrations
No pending migrations to apply.

resolve --applied hech qanday SQL bajarmaydi — faqat holat jadvaliga yozuv qo'shadi. Bu TypeORM'dagi migration:run --fake ning aynan o'zi (TypeORM).

Diqqat: resolve --applied ni faqat bazaning sxemasi fayl bilan haqiqatan mos bo'lganda ishlating. Mos bo'lmasa — siz holat jadvaliga yolg'on yozasiz va keyingi migratsiyalar noto'g'ri bazaga qo'llanadi. Kanon bu moslikni pg_dump solishtiruvi bilan isbotlagan (yuqorida — farq faqat _prisma_migrations).

4.4 _prisma_migrations ichida

Kanon yangi bazada qo'llangandan keyin:

text
 migration_name | tugagan | applied_steps_count |   checksum   
----------------+---------+---------------------+--------------
 0_init         | t       |                   1 | 98ea3d9d80bd
(1 row)

(checksum — SHA-256 ning boshi, kanon so'rovida qisqartirilgan.) Jadval tuzilmasi kanon pg_dump idan: id, checksum, finished_at, migration_name, logs, rolled_back_at, started_at, applied_steps_count. Holatni o'zimiz o'qish mumkin. Biz shu tuzilmani bo'sh bazada qo'lda yaratib, ikki holatni sinadik (biz ishga tushirdik, PostgreSQL 17.6):

sql
CREATE TABLE _prisma_migrations (
  id                  varchar(36)  PRIMARY KEY,
  checksum            varchar(64)  NOT NULL,
  finished_at         timestamptz,
  migration_name      varchar(255) NOT NULL,
  logs                text,
  rolled_back_at      timestamptz,
  started_at          timestamptz  NOT NULL DEFAULT now(),
  applied_steps_count integer      NOT NULL DEFAULT 0
);
INSERT INTO _prisma_migrations
  (id, checksum, migration_name, finished_at, applied_steps_count)
VALUES
  ('a1', '98ea3d9d80bd', '0_init', now(), 1),
  ('a2', 'c0ffee000001', '20261025120000_toliq_ism_expand',
   NULL, 0);
SELECT migration_name,
  CASE WHEN finished_at IS NOT NULL THEN 'qo''llangan'
       WHEN rolled_back_at IS NOT NULL THEN 'bekor qilingan'
       ELSE 'yiqilgan' END AS holat
FROM _prisma_migrations ORDER BY migration_name;

Natija:

text
CREATE TABLE
INSERT 0 2
         migration_name          |   holat    
---------------------------------+------------
 0_init                          | qo'llangan
 20261025120000_toliq_ism_expand | yiqilgan
(2 rows)

Qoida oddiy: finished_at bor — qo'llangan; rolled_back_at bor — resolve --rolled-back bilan bekor deb belgilangan; ikkalasi ham yo'q — boshlangan, lekin tugamagan (yiqilgan yoki hozir bajarilyapti). Aynan shu mantiqni kanon holat 40 da server ishga tushishida tekshiradi (Migratsiyani deploy jarayonida qo'llash).

5. migrate dev --create-only va drift

5.1 Birinchi urinish: Prisma "tuzatmoqchi" bo'ldi

Baseline'dan keyin kanon tekshirdi: "schema.prisma va migratsiyalar bir-biriga mosmi?" Buning eng yaxshi usuli — migrate dev --create-only: agar mos bo'lsa, bo'sh migratsiya chiqadi. Birinchi urinishda esa Prisma shuni yozdi:

sql
-- DropIndex
DROP INDEX "vazifalar_qidiruv_idx";

-- AlterTable
ALTER TABLE "vazifalar" ALTER COLUMN "tartib" DROP NOT NULL,
ALTER COLUMN "qidiruv" DROP DEFAULT;

Uchta "tuzatish" — uchchalasi ham zararli:

  1. DROP INDEX vazifalar_qidiruv_idx — full-text qidiruv indeksi (Postgres'da full-text search). schema.prisma da u yozilmagan edi, Prisma "ortiqcha" deb o'chirmoqchi bo'ldi.
  2. tartib DROP NOT NULL — sxemada tartib Int? (ixtiyoriy) edi, chunki qiymatni trigger qo'yadi. Prisma bazani sxemaga moslab, cheklovni olib tashlamoqchi bo'ldi.
  3. qidiruv DROP DEFAULT — db pull qidiruv ni @default(dbgenerated("to_tsvector(…)")) deb o'qigan edi. Bu xato: ustun GENERATED, DEFAULT emas.

Agar bu migrate dev (--create-only siz) bo'lganda — uchchalasi darhol qo'llanardi.

5.2 Tuzatish — sxemani, bazani emas

Kanon schema.prisma ni bazaga moslashtirdi:

prisma
model Vazifa {
  // … berilmasa trigger qo'yadi (013): "qiymatni baza beradi"
  tartib  Int                      @default(dbgenerated())
  // generated tsvector (104) — Prisma tegmaydi
  qidiruv Unsupported("tsvector")? @default(dbgenerated())

  @@index([qidiruv], type: Gin, map: "vazifalar_qidiruv_idx")
}

@default(dbgenerated()) — bo'sh qavslar bilan: "qiymatni baza o'zi beradi, menga ahamiyati yo'q". create() da maydon ixtiyoriy bo'ladi, Prisma esa ustunga tegmaydi. Ikkinchi urinish:

text
-- This is an empty migration.

Bo'sh migratsiya — schema.prisma va migratsiyalar endi mos (drift yo'q). Kanon uni o'chirdi (u faqat tekshiruv edi). Shu o'zgarish bilan prisma-ombor.ts dan tartib: q.tartib ?? 0 vaqtinchalik yechimi ham olib tashlandi — endi tartib turi number (null emas).

5.3 Qo'lda to'ldirish naqshi

Yangi o'zgarish kerak bo'lganda (masalan CHECK bilan yangi ustun):

  1. schema.prisma da maydonni qo'shasiz.
  2. npx prisma migrate dev --create-only --name muddat_eslatma — Prisma faqat ustunni yozadi.
  3. Faylni ochib, Prisma bilmaydigan qismini qo'shasiz: CHECK, trigger, lock_timeout, NOT VALID.
  4. npx prisma migrate dev — endi to'ldirilgan faylni qo'llaydi.
  5. Faylni review'ga yuborasiz.

Kanon holat 38 dagi expand-contract migratsiyalari aynan shunday yozilgan — Zero-downtime: expand-contract.

Tekshirib ko'ring: --create-only bilan yaratilgan faylni tahrirladingiz va migrate dev bilan qo'lladingiz. Keyin yana tahrirladingiz. Nima bo'ladi?

Javob

migrate dev checksum'ni tekshiradi: qo'llangan fayl o'zgargan — u drift deb hisoblaydi va lokal bazani qayta qurishni (reset) taklif qiladi. Lokal bazada bu muammo emas. Lekin fayl allaqachon push qilingan bo'lsa — qoida buzildi: boshqa muhitlarda eski variant qo'llangan. Kanon topilmasi ham bor: tahrirlangan faylni migrate status sezmadi ("up to date") — checksum'ni faqat migrate dev tekshiradi.

6. reset, db push va yiqilgan migratsiya

6.1 migrate reset

migrate reset — bazani o'chirib (DROP SCHEMA / qayta yaratish), hamma migratsiyani noldan qo'llaydi. Lokal bazani "toza holatga" qaytarish uchun qulay. Prodakshn DATABASE_URL bilan ishga tushirish — hamma ma'lumotning yo'qolishi. IlmHamroh'ning o'z platformasi qoidalarida ham db:reset prodakshnda taqiqlangan.

Kanon yana bir yon ta'sirni topgan: baza qayta qurilsa, Redis'dagi eski kesh va avlod raqami qoladi (Caching naqshlari va invalidatsiya). Reset — faqat bazani tozalaydi, ilovaning boshqa holatini emas.

6.2 db push

prisma db push — schema.prisma ni bazaga to'g'ridan-to'g'ri qo'llaydi: migratsiya fayli yo'q, holat jadvali yo'q. Qachon foydali: prototip, "sxemani tez sinab ko'raman", tashlab yuboriladigan baza. Qachon taqiq: migratsiyalar bilan boshqariladigan har qanday baza — db push drift yaratadi va keyingi migrate dev reset talab qiladi. Bizning sxemada esa u 70+ obyektni bilmagani uchun bazani "Prisma tasavvuridagi" holatga keltirishga urinadi — migrate dev ning birinchi urinishidagi kabi.

6.3 Yiqilgan migratsiya: P3018 va P3009

Kanon muhim narsani o'lchagan: migrate deploy migratsiyani tranzaksiyaga o'ramaydi. Yarmida 1/0 bo'lgan migratsiya:

text
Applying migration `1_yarim`
Error: P3018
A migration failed to apply. New migrations cannot be applied before the error is recovered from. Read more about how to resolve migration issues in a production database: https://pris.ly/d/migrate-resolve
Migration name: 1_yarim
Database error code: 22012
Database error:
ERROR: division by zero

Birinchi ALTER (birinchi_qadam ustuni) bazada qoldi, _prisma_migrations da 1_yarim — tugallanmagan. Keyingi deploy:

text
Error: P3009
migrate found failed migrations in the target database, new migrations will not be applied. Read more about how to resolve migration issues in a production database: https://pris.ly/d/migrate-resolve

Prisma to'xtadi — to'g'ri. Butun voqea jadvalda:

Qadam Buyruq Bazada _prisma_migrations
1 deploy: birinchi ALTER birinchi_qadam paydo bo'ldi 1_yarim boshlandi
2 deploy: 1/0 ustun qoldi (tranzaksiya yo'q) tugamagan — P3018
3 keyingi deploy o'zgarmadi P3009, hech narsa qo'llanmaydi
4 qo'lda tuzatish + resolve siz tozalaysiz --rolled-back yoki --applied (hujjat bo'yicha)

Endi qo'lda: (1) bazani migratsiyadan oldingi holatga qaytaring (qolgan ustunni o'chiring) yoki migratsiyaning qolgan qismini qo'lda bajaring; (2) holatni belgilang — migrate resolve --rolled-back 1_yarim (keyin tuzatilgan faylni qayta deploy) yoki --applied 1_yarim (qo'lda tugatgan bo'lsangiz). Bu tartib Prisma hujjatida ("Patching and hotfixing"); resolve --rolled-back ni biz sinamadik. Batafsil o'lchov — Zero-downtime: expand-contract.

O'z SQL'ingizni BEGIN; … COMMIT; bilan o'rashingiz mumkin (PostgreSQL DDL'ni qaytaradi) — lekin CREATE INDEX CONCURRENTLY bor faylda emas.

7. Ko'p uchraydigan xatolar

1. Prodakshnda migrate dev. Shadow baza huquqi yo'qligi bilan yiqiladi yoki, yomoni, drift topib reset taklif qiladi. Tuzatish: prodakshn va CI'da faqat migrate deploy.

2. P3005 The database schema is not empty. Mavjud bazaga baseline'siz deploy. Tuzatish: 0_init + migrate resolve --applied 0_init (sxema mosligini tekshirib).

3. migrate dev foydali obyektlarni o'chirmoqchi. schema.prisma da yo'q indeks, Int? bo'lgan NOT NULL ustun, noto'g'ri dbgenerated. Tuzatish: har doim --create-only, faylni o'qish; sxemani bazaga moslash (@default(dbgenerated()), @@index(…, map:)).

4. P3009 — yiqilgan migratsiya to'sib turibdi. Tuzatish: bazani qo'lda tuzatish, migrate resolve --rolled-back yoki --applied.

5. PrismaConfigEnvError: Cannot resolve environment variable. Prisma 7 .env ni o'zi o'qimaydi (kanon topilmasi, holat 20). Tuzatish: node --env-file-if-exists=.env … (kanon npm run db:migrate) yoki prisma.config.ts da URL faqat bor bo'lsa.

6. Qo'llangan faylni tahrirlash. migrate status sezmaydi. Tuzatish: yangi migratsiya.

8. Mashqlar

SQL yechimi tekshirilgan (biz ishga tushirdik, PostgreSQL 17.6).

1-mashq (oson)

Har vaziyatga bitta buyruq tanlang:

  • (a) prodakshnga yangi relizni chiqaryapsiz;
  • (b) lokal bazangiz chalkashib ketdi, noldan qurmoqchisiz;
  • (c) 2 yillik ma'lumotli bazani Prisma Migrate'ga o'tkazyapsiz, 0_init tayyor;
  • (d) schema.prisma ga maydon qo'shdingiz va SQL'ga CHECK qo'shmoqchisiz.
Yechim

(a) prisma migrate deploy. (b) prisma migrate reset (faqat lokal!). (c) prisma migrate resolve --applied 0_init — sxema mosligini tekshirgandan keyin; keyin migrate status → "up to date". (d) prisma migrate dev --create-only --name …, faylga CHECK ni qo'shish, keyin prisma migrate dev.

2-mashq (o'rta)

schema.prisma da model Vazifa { … tartib Int? } (bazada NOT NULL, trigger qo'yadi). migrate dev --create-only qanday SQL yozadi va nega? Ikki xil tuzatishni ayting va qaysi biri to'g'ri ekanini asoslang.

Yechim

ALTER TABLE "vazifalar" ALTER COLUMN "tartib" DROP NOT NULL; — Prisma bazani sxemaga moslaydi: sxemada ixtiyoriy, bazada majburiy → cheklovni olib tashlaydi.

Tuzatish A — tartib Int (majburiy). Unda prisma.vazifa.create() tartib ni talab qiladi, trigger esa ishlamay qoladi (ilova o'zi raqam berishi kerak). Noqulay. Tuzatish B — tartib Int @default(dbgenerated()): bazada NOT NULL, Prisma'da create() da ixtiyoriy, qiymatni trigger beradi, migratsiya bo'sh. To'g'ri — B (kanon tanlovi).

3-mashq (qiyin)

«_prisma_migrations ichida» bo'limidagi jadvalga uchinchi qator qo'shing: 20261025120100_toliq_ism_contract, rolled_back_at = now(), finished_at yo'q. So'rovni o'zgartiring: har holat bo'yicha sonini chiqarsin (holat, soni), holat nomi bo'yicha tartiblangan. Ishora: GROUP BY (Agregatlar).

Yechim
sql
CREATE TABLE _pm (
  id varchar(36) PRIMARY KEY, checksum varchar(64) NOT NULL,
  finished_at timestamptz, migration_name varchar(255) NOT NULL,
  rolled_back_at timestamptz,
  applied_steps_count integer NOT NULL DEFAULT 0);
INSERT INTO _pm (id, checksum, migration_name, finished_at,
  rolled_back_at) VALUES
  ('a1', 'x', '0_init', now(), NULL),
  ('a2', 'y', '20261025120000_toliq_ism_expand', NULL, NULL),
  ('a3', 'z', '20261025120100_toliq_ism_contract', NULL, now());
SELECT CASE WHEN finished_at IS NOT NULL THEN 'qo''llangan'
            WHEN rolled_back_at IS NOT NULL THEN 'bekor qilingan'
            ELSE 'yiqilgan' END AS holat,
       count(*) AS soni
FROM _pm GROUP BY 1 ORDER BY 1;
DROP TABLE _pm;

Natija:

text
CREATE TABLE
INSERT 0 3
     holat      | soni 
----------------+------
 bekor qilingan |    1
 qo'llangan     |    1
 yiqilgan       |    1
(3 rows)

DROP TABLE

GROUP BY 1 — birinchi ustun (CASE ifodasi) bo'yicha. Jadvalni _pm deb atadik va oxirida o'chirdik — dars bazasidagi _prisma_migrations ga tegmaslik uchun. Prisma uchun yiqilgan qator — P3009 sababi; bekor qilingan — to'smaydi.

9. Loyiha qadami

9.1 Holat 36: baseline

Holat 36 — 35- va 36-darslarning umumiy holati, commit shu darsda (35-darsda "hali commit qilmang" degan edik):

bash
git add prisma/migrations/0_init prisma/migrations/migration_lock.toml
git add prisma/schema.prisma .env.example
git add src/vazifalar/prisma-ombor.ts
M='feat(db): Prisma Migrate — 0_init baseline (sql/ fayllari),'
M+=' migrate deploy skripti'
git commit -m "$M"

O'zgarishlar:

  • prisma/migrations/0_init/migration.sql — sql/ ning namunasiz fayllari (001–014, 101, 103–106) birlashmasi; migration_lock.toml.
  • schema.prisma — tartib Int @default(dbgenerated()), qidiruv … @default(dbgenerated()), @@index([qidiruv], type: Gin, map: "vazifalar_qidiruv_idx") (drift'siz).
  • prisma-ombor.ts — tartib endi number, ?? 0 olib tashlandi.
  • .env.example — izoh: "Migratsiya: npm run db:migrate (prisma migrate deploy). Mavjud bazada birinchi marta: npx prisma migrate resolve --applied 0_init".

npm run db:migrate skripti holat 20 dan beri bor: node --env-file-if-exists=.env node_modules/prisma/build/index.js migrate deploy (Prisma 7 .env ni o'zi o'qimagani uchun).

9.2 Tekshiruv

Kanon tekshiruvi (holat 36): tip/lint 0, testlar 99/99, yangi bazaga migrate deploy == sql/ dan qurilgan baza, migrate status — up to date, jonli API 9/9 (ikkala ombor bilan). O'zingizda:

bash
npm run db:migrate
npx prisma migrate status
npm run check

Kutilgan: "No pending migrations to apply." (yoki birinchi marta — 0_init qo'llandi), "Database schema is up to date!", testlar o'tadi.

10. Real ishda

  • Prisma loyihalarida prisma/migrations papkasi — kod review'ning eng diqqatli qismi. "migration.sql da DROP bormi?" — birinchi savol.
  • Baseline — ORM'ga ko'chishda ham, migratsiya vositasini almashtirishda ham (Sequelize → Prisma) kerak bo'ladigan amal.
  • CI odatda migrate deploy ni bo'sh bazada va migrate diff bilan "schema.prisma va migratsiyalar mosmi?" tekshiruvini bajaradi (Migratsiyani deploy jarayonida qo'llash).
  • Intervyuda: "migrate dev va deploy farqi?", "shadow baza nima?", "mavjud bazani qanday ulaysiz?".

Xulosa

  • migrate dev — lokal: shadow baza, farq hisoblash, yangi fayl; migrate deploy — prodakshn: faqat tayyor fayllarni qo'llaydi.
  • Kanon o'lchovi: Prisma sxemadan 15 CHECK, 8 funksiya, 6 trigger, 5 policy, 7 generated ustunning birortasini yozmadi — boy sxemada manba SQL fayllar.
  • Baseline: 0_init + migrate resolve --applied 0_init; baseline'siz deploy — P3005.
  • --create-only — har doim; kanonning birinchi urinishida Prisma indeksni o'chirmoqchi va NOT NULL ni olib tashlamoqchi bo'ldi.
  • migrate deploy tranzaksiyasiz: yarim migratsiya P3018, keyingisi P3009 — migrate resolve bilan qo'lda tiklanadi.
  • migrate reset va db push — faqat lokal/prototip.

Keyingi dars: Xavfli migratsiyalar va qulflar — qaysi ALTER jadvalni soniyalab to'xtatadi: kanon 500 000 qatorli jadvalda o'lchagan qulflar, CONCURRENTLY, NOT VALID va lock_timeout.

Manbalar

  • Prisma hujjati — Prisma Migrate: development and production, shadow database, baselining, migrate diff, patching and hotfixing (migrate resolve): https://www.prisma.io/docs/orm/prisma-migrate
  • Prisma xato kodlari (P3005, P3009, P3018): https://www.prisma.io/docs/orm/reference/error-reference
  • IlmHamroh kanon: holat 36, t36-migrate-1, t36-migrate, t36-migrate-diff.sql, t38-expand-contract, tekshiruv-36 (Prisma 7.10.1, PostgreSQL 18.6, 2026-10-25); _prisma_migrations SQL'i — biz ishga tushirdik (PostgreSQL 17.6, Windows 11), 2026-10-27.
Ulashish:Telegram'da

Izohlar (0)

Izoh yozish uchun kiring.

  • Hozircha izoh yo'q. Birinchi bo'ling!
Prisma Migrate: migrate dev, deploy, baseline, diff va resolve — IlmHamroh