Привет, я Никита Волков - архитектор, консультант и автор hasql, одного из двух основных драйверов PostgreSQL для Haskell, который используется в крупных проектах вроде PostgREST и IHP. После 25 лет в IT и слишком большого числа ночных инцидентов из-за дрейфа схемы я выложил в open source то, чего мне не хватало еще десять лет назад: pGenie.

Дальше - история о том, как я выпустил популярный ORM в 2012 году… потом похоронил его… и в итоге понял, что самой базе данных и должна принадлежать роль единственного источника истины.

2012: я написал ORM

Тогда я был типичным веб-разработчиком своего времени. Единственное, что мне нужно было - это CRUD. Проблемы производительности можно было оставить на “потом”. Деплой сводился к ssh + git pull. Миграций фактически не было.

Я написал SORM - ORM-фреймворк для Scala - и выложил его в open source. Вместо того чтобы рассматривать объекты как изменяемые представления базы данных, он обменивал их с БД как неизменяемые значения. Это казалось свежей идеей. Проект получил отклик. Некоторое время это выглядело как успех.

Потом пришла реальность.

  • Каждый нетривиальный запрос показывал ограничения DSL.

  • Синхронизация кодовой модели с реальной схемой базы данных превратилась в неисчерпаемый источник головной боли.

  • По сути, я изобретал худшую версию SQL только ради того, чтобы сделать интеграцию “безопаснее”.

В 2014 году я остановил разработку. В 2016-м прекратил поддержку. Вывод: абстрагироваться над SQL - обычно ошибка.

Инсайт №1: вместо того чтобы заменять SQL, нужно просто улучшать интеграцию с ним

Вместо того чтобы строить слои абстракции поверх SQL нужно делать работу с сырым SQL максимально безопасной и удобной.

Так в 2014 году появился hasql - драйвер, который принимает SQL как есть и даёт компонуемые абстракции в поддержку этого подхода. Сегодня это один из двух основных драйверов Postgres в экосистеме Haskell и самый эффективный из них.

С этой библиотекой я нашёл оптимальную точку интеграции.

Инсайт №2: оптимальной точкой интеграции с БД является запрос

Не модель из бизнес-логики. Не структура строки таблицы. Сам запрос.

Запрос определяет структуру параметров, которые ему нужны, и то, что он возвращает. Попытки переиспользовать “типы строк” между разными запросами только создают скрытые зависимости и закладывают будущие поломки из разряда “меняем один запрос, ломается другой”. Натягивание моделей из бизнес-логики на сущности БД эскалирует эту проблему на другие слои приложения. А связывание с типами API - это вообще катастрофа, приводящая к абсурдным ситуациям, когда изменение API ломает интеграцию с БД.

Эта идея дала прочную основу, но чего-то всё ещё не хватало.

Каждый запрос приходилось сопровождать самописными кодеками, а SQL-строка никак не валидировалась. Поэтому в 2019 году я выпустил hasql-th - библиотеку проверки SQL-синтаксиса на этапе компиляции, основанную на порте парсера PostgreSQL. Это упростило систему и сделало ее безопаснее, но всё ещё было недостаточно. Не хватало валидации запросов на соответствие фактической схеме.

В течение этих лет я наблюдал проекты, которые пытались решить эту проблему через подключение к базе данных на этапе компиляции. Но это всегда казалось костылем, который делал сборки невоспроизводимыми. Я искал решение, которое могло бы жить целиком в коде, развиваться в репозитории и не зависеть от внешней инфраструктуры, и в итоге нашёл его.

Инсайт №3: миграции + запросы = API базы данных

Вот ментальная модель, которая изменила для меня всё:

Если рассматривать сервер Postgres как микросервис, тогда:

  • Миграции = контракт (как схема OpenAPI для REST).

  • Запросы = операции (эндпойнты в OpenAPI).

Ваше приложение - всего лишь клиент этого API. Значит, база данных первична. Значит, код приложения вторичен.

Это и есть подход DB-First (или SQL-First).

И тут всё наконец сложилось. Схема живет в SQL-миграциях. Запросы живут в файлах .sql. Всё это попадает в репозиторий и становится объектом разработки, тестирования и ревью. Всё остальное - типы, кодеки, рекомендации по индексам - можно автоматически выводить и безопасно интегрировать в кодовую базу с помощью компиляторов языков программирования с проверкой типов.

2022–2026: от закрытого SaaS-эксперимента к open source

Впервые я выпустил pGenie как SaaS в 2022 году. Выяснилось, что компании не хотят отправлять свои схемы и запросы третьей стороне. Что ж, пришлось пересмотреть стратегию.

В 2026 году я выложил pGenie полностью в open source и перешёл на бизнес-модель OSS + Consulting:

github.com/pgenie-io/pgenie

Это простой CLI. Вы указываете ему папки migrations/ и queries/. Он поднимает реальный контейнер PostgreSQL, воспроизводит схему, выполняя миграции, подготавливает запросы, анализирует information_schema и генерирует на 100% типобезопасный клиентский код для различных языков программирования через плагины. Сейчас Java, Rust и Haskell полностью поддерживаются как такие плагины. Ведётся разработка для C# и TypeScript.

Что на самом деле дает pGenie

  • SDK без лишнего шаблонного кода и с типобезопасностью

  • Поддержку продвинутых возможностей Postgres: JSONB, массивов, составных типов, multirange, расширений и т. д.

  • Децентрализованные генераторы кода, написанные на безопасном и воспроизводимом DSL Dhall

  • Файлы сигнатур, которые ловят дрейф схемы на этапе сборки

  • Автоматические рекомендации по индексам и предупреждения о последовательном сканировании

Полное сопоставление исходного SQL и сгенерированного клиентского кода для Java, Rust и Haskell есть в демо-репозитории - попробуйте сами.

Почему это особенно важно сейчас, в эпоху ИИ

LLM отлично пишут SQL. Но они не могут гарантировать, что этот SQL продолжит работать после следующей миграции.

pGenie закрывает этот разрыв: ИИ пишет запрос, pGenie проверяет его по реальной схеме, вы за секунды получаете предсказуемо структурированный типобезопасный SDK.

SQL-First + AI = максимум скорости без сюрпризов.


Готовы перестать бороться с базой данных?