Привет, я Никита Волков - архитектор, консультант и автор 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:
Это простой 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 = максимум скорости без сюрпризов.
Готовы перестать бороться с базой данных?
Изучите документацию: pgenie.io/docs
Задавайте вопросы и делитесь идеями: github.com/pgenie-io/pgenie/discussions
Поставьте ⭐ на GitHub: github.com/pgenie-io/pgenie