Перейти к содержимому
ГоМастер

Поиск по урокам

Найдите урок, курс, термин или раздел

GORM, sqlc или ent: как работать с базой данных в Go

GORM — привычный ORM с автоматическими миграциями, sqlc — кодогенерация типобезопасных запросов из чистого SQL, ent — графовая ORM Facebook со строгой схемой. Выбор зависит от того, кто пишет запросы: вы или библиотека.

Подбор под ваши приоритеты

Двигайте ползунки — насколько для вас важен каждый критерий (0 — не важен, 5 — критично). Счёт пересчитывается на лету: это взвешенное среднее оценок библиотек по критериям, а не бенчмарк.

Ошибки ловит компилятор, не рантайм

Понятный и предсказуемый SQL

Первый CRUD за час

Has-many, many-to-many, автосхема

Документация и привычность подхода

Взвешенный счёт

  • GORMваш матч76
  • sqlc72
  • ent72

Под ваши веса лидирует GORM: быстрые прототипы и типовые crud-приложения с простыми связями.

После первого CRUD на database/sql вопрос «как работать с БД в Go» распадается на три стратегии: ORM с активной записью, кодогенерация из SQL и схема-первая ORM. GORM, sqlc и ent представляют ровно эти три подхода, и споры вокруг них — классика чатов Go-разработчиков. На этой странице всё три библиотеки читают одну и ту же задачу: список задач с фильтром и созданием записи.

GORM — самый распространённый ORM для Go: структура-модель с тегами, автоматические миграции, связи has-many/belongs-to, хуки до и после сохранения. Порог входа минимальный, CRUD пишется без единой строки SQL. Плата за удобство — магия: часть ошибок (N+1 в ассоциациях, неожиданные каскады) всплывает в рантайме, а сложные запросы всё равно уходят в Raw SQL.

sqlc идёт от обратного: вы пишете обычный SQL в .sql-файлах с аннотациями, а генератор создаёт строго типизированный Go-код. Никакой магии в рантайме — то, что скомпилировалось, то и выполнится; ошибки в запросах ловит компилятор. ent, созданный в Facebook (Ariel Mashraki), описывает схему на Go-коде и генерирует графовую ORM: предикаты, транзитивные запросы через edges, приватные поля и code-first миграции. Это мощно для связанных данных, но добавляет слой абстракции и время на обучение.

Практическое правило, которое подтверждает и наша программа обучения: аналитические и отчётные запросы удобнее писать sqlc-путём, быстрый прототип с миграциями и связями — GORM, домены с плотным графом связей (соцсети, каталоги, права) — ent. Каждый подход разобран в отдельном курсе: GORM, sqlc и ent — по 25 уроков с практикой в браузере.

Одна и та же задача в каждой библиотеке

Задача-эталон для этого сравнения: посмотрите на разницу в церемониях, типах и обработке ошибок — так выбор ощущается, а не только описывается словами.

Классический ORM: модели с тегами, автосхема, CRUD без SQL

package main

import (
  "gorm.io/driver/sqlite"
  "gorm.io/gorm"
)

type Task struct {
  gorm.Model
  Title  string
  Done   bool
}

func main() {
  db, _ := gorm.Open(sqlite.Open("app.db"), &gorm.Config{})
  db.AutoMigrate(&Task{})

  db.Create(&Task{Title: "Выучить GORM"})

  var tasks []Task
  db.Where("done = ?", false).
    Order("created_at DESC").
    Limit(10).
    Find(&tasks)
}

Сильные и слабые стороны

GORM

Классический ORM: модели с тегами, автосхема, CRUD без SQL

  • Автоматические миграции и связи прямо из структур
  • Огромное сообщество, плагины (soft delete, шифрование, пул)
  • Быстрый старт: прототип на SQLite за вечер
  • Часть поведения скрыта в рантайме: N+1 и каскады
  • Сложные выборки всё равно пишутся Raw SQL

Берите, если: быстрые прототипы и типовые crud-приложения с простыми связями.

sqlc

Кодогенерация из чистого SQL: пишете запрос — получаете типы

  • Полный контроль: SQL остаётся SQL, ничего не генерируется в рантайме
  • Строгая типизация: опечатка в колонке ломает сборку
  • Нулевая зависимость в бинарнике — сгенерированный код это просто database/sql
  • Миграции и связи — сами (goose, atlas, golang-migrate)
  • Нет рантайм-построителя запросов: динамика собирается руками

Берите, если: команды, которые знают sql и хотят держать запросы в явном виде.

ent

Схема-первая ORM от Facebook: граф связей и генерация кода

  • Схема описывается кодом: поля, edges, индексы, приватность — и валидируется
  • Графовые запросы: транзитивные связи через edges читаются декларативно
  • Мощная кодогенерация: предикаты, хуки, privacy-политики
  • Крутой порог входа: нужно выучить схему и сгенерированный API
  • Автосхема слабее миграционного инструмента — для продакшена нужен atlas

Берите, если: домены с плотными связями: каталоги, соцграфы, права доступа.

Оценки по критериям

Шкала 1-5: экспертная оценка команды проекта по практике, а не синтетика.

Сравнение GORM, sqlc, ent по критериям
КритерийGORMsqlcent
ТипобезопасностьОшибки ловит компилятор, не рантайм
Контроль над SQLПонятный и предсказуемый SQL
Скорость разработкиПервый CRUD за час
Связи и миграцииHas-many, many-to-many, автосхема
Порог входаДокументация и привычность подхода

Вердикт: когда что выбирать

Выбор сводится к вопросу «кто пишет запросы»: GORM пишет их за вас (и иногда неожиданно), sqlc оставляет SQL вам и даёт типы, ent описывает связи схемой и генерирует графовый API. Всё три — рабочие пути в продакшене; ошибкой чаще бывает не выбор, а смешение трёх подходов в одном проекте.

MVP и прототип за выходныеGORMAutoMigrate и связи из коробки — от идеи до схемы за час
Сервис со сложными выборками и ревью SQLsqlcЗапросы видны целиком, типы проверяет компилятор
Граф связанных сущностей и access-политикиentEdges и privacy-политики описываются один раз в схеме

А что выбрали вы?

Кликните по своему выбору — голос сохранится только в вашем браузере (персональные данные никуда не отправляются).

Частые вопросы

Что быстрее: GORM, sqlc или ent?

sqlc почти не добавляет накладных расходов — сгенерированный код использует database/sql напрямую. ent близок к нему после генерации. GORM в типовых CRUD сопоставим, но рефлексия и хуки заметны на горячих путях; в любом случае база и сеть остаются главным фактором.

Можно ли смешивать sqlc и GORM в одном проекте?

Можно, но лучше выбрать один основной подход: GORM для миграций и простых CRUD, а тяжёлые отчёты — через сгенерированные sqlc-методы на том же соединении. Следите за единственным источником правды по схеме.

Как sqlc делает запросы типобезопасными?

Генератор парсит ваши SQL-файлы по аннотациям (-- name: ListTasks :many), сверяет колонки со схемой и создаёт функции с конкретными типами аргументов и результатов. Ошибка в имени колонки — ошибка компиляции, а не продакшен-инцидент.

Нужны ли миграции в ent?

Да. ent умеет создавать таблицы из схемы, но для контролируемых миграций в продакшене рекомендуется atlas или ручные SQL-миграции — так вы получаете ревью, историю и откат.

Другие сравнения