Drizzle супраць Prisma: выбар ORM для TypeScript без хайпу
Параўнанне Drizzle і Prisma па дызайне схемы, стылі запытаў, укладзеных запісах, міграцыях, транзакцыях і прадукцыйнасці — з парадамі, што якой камандзе пасуе.
Крыніцы: 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.