Галоўная / Артыкулы

Drizzle супраць Prisma: выбар ORM для TypeScript без хайпу

Параўнанне Drizzle і Prisma па дызайне схемы, стылі запытаў, укладзеных запісах, міграцыях, транзакцыях і прадукцыйнасці — з парадамі, што якой камандзе пасуе.

Выдавец: REACTAPP.TOP7 хв чытання1588 слоў

Крыніцы: Drizzle vs Prisma: Choosing the Right TypeScript ORM in 2026 (Deep Dive)

Drizzle ORM і Prisma — гэтыя два назвы частаеўшыяся пад час выбору ORM для праекта на TypeScript. Яны рашаюць тую ж проблему — ператварэнне доступу да базы дадзеных у код з тыпамі, але выклікаюць працою на працоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнасупрацоўнас

У 2022 году з’явіўся Drizzle і швыдка распростраўляўся серэд распрацоўшчыкаў, якія хацялі контроль без дадатковай вагі. Ён ў першую чаргу базуецца на TypeScript: табліцы, зв’язкі і запыты адзначаюцца ў TypeScript. Справядлівыя апісанні — цэлкам тонкі, тыпаваны шар над SQL. Тыпы выважваюцца аўтаматычна, необработаны SQL застаецца безпечным з точкі зору тыпаў, а дызайн падходзіць для коду, чутлівага да выконавачых характэрыстыкаў. Падтрымліваюцца PostgreSQL, MySQL, SQLite і SQL Server.

Prisma з’явіўся ранейш, у 2018 годзе, і створыў свою рэпутацыю на аспектах досвіду распрацоўшчыка, продуктыўнасці і інструментаў. Мадэль дадзеных знаходзіцца у файле .prisma, напісанам на мове Prisma Schema Language (PSL), а команда prisma generate ператварае яе на кліент з повнай тыпаванасцю і API высокага рангу. Связі між элементамі дадзеных адбываюцца аўтаматычна, а екасыстэма Prisma ёсць большаю і болей зрэлай, уключаючы Prisma Studio — візуальны браузер і рэдагувальнік дадзеных. Падтрымваныя базы дадзеных включаюць PostgreSQL, MySQL, SQLite і MongoDB, а таксама іншыя.

Апішанне схемы

Тут філасофіі найбольш помітна разлічаюцца, і выбор вплывае на ўседзённую працу і безпеку тыпаў.

Drizzle: код першы

Схема Drizzle — гэта звычны TypeScript. Табліцы, столбцы і связі знаходзяцца ў той жа мове, што і сама аплікацыя, таму няма кроку генеравання, а змяны адразу праказуюцца ў рэдагувальніку.

import { pgTable, serial, varchar, text, integer, timestamp } from "drizzle-orm/pg-core";

// Authors table
export const authors = pgTable("authors", {
  id: serial("id").primaryKey(),
  name: varchar("name", { length: 100 }).notNull(),
  bio: text("bio"),
});

// Books table referencing Authors
export const books = pgTable("books", {
  id: serial("id").primaryKey(),
  title: varchar("title", { length: 150 }).notNull(),
  summary: text("summary"),
  authorId: integer("author_id")
    .notNull()
    .references(() => authors.id),
  publishedAt: timestamp("published_at").defaultNow(),
});

Пакалькі тыпы выважваюцца адразу, таму рэзултат запытку мае вядомую структуру без якіх-лібо дадатковых файлаў схемы. эта скарочвае неспакоі пад час выканання.

Prisma: схема спачатку

Prisma зберагае модэль у окрэмым файле .prisma:

model Author {
  id    Int     @id @default(autoincrement())
  name  String
  bio   String?
  books Book[]
}

model Book {
  id          Int      @id @default(autoincrement())
  title       String
  summary     String?
  publishedAt DateTime @default(now())
  authorId    Int
  author      Author   @relation(fields: [authorId], references: [id])
}

Схема чыста аддзелена ад коду прыемліка. Пасля кожных змян prisma generate перабудоввае кліента, ўнаследкі чаго тыпы падтрымліваюцься. Для людзей з мінімальнымі знаннямі SQL такая абстракцыя ёсць прыемней, адколькі вы працуеце з генераваным кліентам высокага рэвэля, а не з логікай у стылі SQL. Адзін недзея — гэта ўсё большы слой межу вашым кодам і базайнам дадзеных.

Запіс кэйсаў

Оба падходы даўаюць кэйсы, якія пераканальваюцца на тыпы, але ў яных разны спосаб запісу.

Drizzle

Конструктор кэйсаў ўмышлена ў меры маленькі і прыемны для вікорыстоўвання, і ў яго можна чытаць як у SQL. Калі вы впэўнены ў вікорыстоўванні з’еднанняў і клазаў where, ён здаецца прыродным, а тое, што вы запішыце, точна адпавядае таму, што выканаецца ў базайні дадзеных. У гэтым прыкладзе кнігі з’еднаны з автарамі, а рэзультат фільтруецца і сортаваецца:

const results = await db
  .select({
    bookId: books.id,
    title: books.title,
    publishedAt: books.publishedAt,
    authorName: authors.name,
  })
  .from(books)
  .leftJoin(authors, eq(books.authorId, authors.id))
  .where(eq(authors.id, authorId))
  .orderBy(books.publishedAt);

Вы атрыбуеце тонкі кантроль і высока працэздатнае SQL. Значныя разлікі па прымэру з Prisma прыкметны пад час стварэння сувязаных рэядоў. Drizzle не падтрымляе вкладзеныя змены, таму кожны вставкі ў рэляцыйную базу дадзеных адбываецца вручную, зазвычай у межах транзакцыі, каб усе элементы заставаліся састояльнымі:

const result = await db.transaction(async (tx) => {
  const [newAuthor] = await tx.insert(authors).values({
    name: "Alice",
    bio: "Fantasy author",
  }).returning({ id: authors.id });

  const [newBook] = await tx.insert(books).values({
    title: "The Dream Forest",
    authorId: newAuthor.id,
  }).returning();

  return { newAuthor, newBook };
});

Полная праўдзівасць — гэта плюс. Большая колькасць стандартных элементаў коду — гэта мінус.

Prisma

Prisma выбірае працоўнае напрамянне, працоўнае на протыяўнасці. Вы вызываеце методы на аўтагенераваным кліенце, а база дадзенаў застаецца за дапамогою методаў у стылі об’ектаў. Той самы пошук стае такім:

const results = await prisma.book.findMany({
  where: { authorId },
  select: {
    id: true,
    title: true,
    publishedAt: true,
    author: {
      select: { name: true },
    },
  },
  orderBy: { publishedAt: "asc" },
});

Хто не павінен думаць на SQL, і гэта часткаяе популярнасць Prisma. Ён таксама выглядае выгодна пад час стварэння супаўзвязаных дадзеных, таму што падтрымліваюцца вкладзеныя збіркі дадзеных. Кнігу і яе автара можна стварыць за аднай вызову:

const newBook = await prisma.book.create({
  data: {
    title: "The Dream Forest",
    summary: "A surreal adventure.",
    author: {
      create: {
        name: "Alice",
        bio: "Fantasy author",
      },
    },
  },
});

Няма неабяжлівых ключоў, якія трэба было бы ручна падключаць. Тое, чаго вы пасвячаеце, — гэта візуабельна частка, адколі фактычна выконваная SQL-запіс застаецца для вас невідомай, таму у вас меней кантролю, чым у Drizzle.

Міграцыі

Змена схемы з часам мае значэнне ў будзь-ям рэальным праекце, і обеі інструменты эфектыва справляюцца з гэтым.

Drizzle

Паколькі схема напісана на TypeScript, яна ёсць аднаковым джэрэлам інфармацыі, а CLI (drizzle-kit) генеруе міграцыі на адлікі ў вашых ваказаннях. У робочым працэсе, які базуецца на міграцыях, спачатку генеруецца:

npx drizzle-kit generate

Гэта парабялее чынны стан з дыяграмай TypeScript і запісвае файл міграцыі з змянамі SQL, які можна рэкамендаваць рукою прытымкі да яго выкарыстоўвання. Яго прыкладчык — адзінэцкі каманд:

npx drizzle-kit migrate

Для шырокага протатаванняя таксама існуея спрыткая дорага:

npx drizzle-kit push

Ён перадае схему TypeScript адразу ў базу дадзеных без стварэння файла міграцыі. Гэта шырока і зручна на пачатковым этапе, але без історыі міграцый гэта не падходзіць для працы ў працэсе.

Prisma

У Prisma файл .prisma ёсць аднаковым адказам пра правілы, а інструмент пішае SQL-код для кожных змян. Для застосавання зберажаных міграцый у базе дадзеных вікорыстоўваецца:

npx prisma migrate deploy

У перыядзеўванні каманда prisma migrate dev выконвае стварэнне новага папкі з міграцыямі з SQL-скрыптамі, ўпрацоўвае іх і апдэйтуе табелю історыі. Гэта стварае апрантаваны, пераважна аўтаматычны працэс работы.

Існуе таксама спрытка для стварэння пратаяпаў:

npx prisma db push

Ён безпасебна апдэюе базу дадзэных безпосерэдна, як і Drizzle праз пуш-функцыю, без файлаў міграцыі, таму ён падходзіць толькі для непродакшн-выкарыстання.

Транзакцыі

Оба раштрымуе транзакцыі, з некалькамі малымі разлікамі ў стылі.

Drizzle выкарыстоўвае db.transaction з калбэкам. Кожны запыт унутры яго або успявае, або не успявае адразу, і так як вы працуеце з SQL, вы можаце точна кантроліраваць тое, што выканаецца ў гэтым блаке:

await db.transaction(async (tx) => {
  const newAuthor = await tx.insert(authors).values({
    name: "Alice Walker",
    bio: "Pulitzer Prize-winning author",
  }).returning();

  await tx.insert(books).values({
    title: "Journey to the Mountains",
    summary: "A story about adventure and discovery.",
    authorId: newAuthor[0].id,
  });
});

Prisma адказвае функцыяю prisma.$transaction, якая прыймае або масэву запыткаў, або асінхронны калбэк. Автаматычна выкананыя ўтверджэнне і анулюванне змян:

await prisma.$transaction(async (tx) => {
  const newAuthor = await tx.author.create({
    data: {
      name: "Alice Walker",
      bio: "Pulitzer Prize-winning author",
    },
  });

  await tx.book.create({
    data: {
      title: "Journey to the Mountains",
      summary: "A story about adventure and discovery.",
      authorId: newAuthor.id,
    },
  });
});

Расыянне

Расыянне — гэта тая сфера, дзе філасофіі, якія лежачыя в основе, маюць найбольша значыннае значэнне.

Drizzle ўяўляе сабою лёгкі інструмент, а яго запыткі практычна безпосерэдньа адпавядаюць операцыям базы дадзенаў, таму затраты на абстракцыю ў мінімуме. Гэта корыстна для складных запыткаў, масовых операцый і коду з высокай працэздатнасцю. Заводзячы полны кантроль над з’еднаннямі, транзакцыямі і структурой запыткаў, налаштаванне для прышвычкі да высокай швальнасці стае простым, але гэта выклікае патрэбу розумець SQL і праектаванне баз дадзенаў.

Створаны кліент Prisma скрывае SQL за API высокага рэвэля, што нейкі час паграджвае расыянне, але ў большасці звычайных прыкладоў разліка ў мінімуме. Связі, вкладзеныя запыткі і рэзультаты з адзначэннем тыпа даўаюцца без даплат, што прышвычвае розвіцце. Аднак такая зручнасць іноды можа прынесці SQL, які ў меньшай меры оптымалізаваны, чым запытка, напісаныя рукой з адной стороны.

Выбір між імі

Оба являюцца сучаснымі ORM-сістэмамі, які падтрымляюць TypeScript, з абзярнасцю да тыпаў, можлівасцю міграцый, стварэння адносаў і абмовак, таму выбор залежыць ад прыорытэтаў.

Выберыце Drizzle, калі хочаце застацца бліжэй да SQL, кантролюваць запыты і міграцыі, а таксама патрабуеце прыцяглівай працэздатнасі пад вялікімі чы абавязлівымі навантажэннямі. TypeScript выступае як едынага адказвальнага джэрага інфармацыі, і нічога не застаецца нез’явленым.

Выберыце Prisma, калі каманда хочаце працаваць быстра, сфокусавацца на функцыях і скорыцца аўтаматызацыі для міграцый, запытоў і адносаў. Модэль, які спачатку стварае схему, і генераваны кліент даюць чысты, высокага рэвэля API, які ўдобны для пачатківаўцаў.

Корача:

  • Схема: код на TypeScript (Drizzle) проты файлу .prisma плюс генераванне (Prisma).
  • Запыты: на кшталт SQL і явныя проты у стылі об’ектаў і абстрактныя.
  • Вкладзеныя запісы: ручныя у Drizzle, вбудованыя у Prisma.
  • Эфекты працы: менша вага і лепшая кантроль у працэ, у працы ж выклікаеяцца лёгкая додатковая навантажэнь для большага зручнасці.