Самый надежный способ проверить, работает ли код – запустить его. Компиляторы и линтеры отсеивают ошибки, но не все. Легко написать код, который пройдет компиляцию, но при запуске упадет.

Поэтому языки с REPL-ом такие продуктивные. Любой клочок кода можно выполнить в редакторе и посмотреть, что будет. Это не отменяет тесты и другие практики, но здорово помогает.

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

Чтобы выбрать данные, я открываю PGAdmin и пишу SQL ручками. Сперва убеждаюсь, что он вернул то, что я ожидал. Потом смотрю план, проверяю, попал ли в индексы. Если все в порядке, переношу запрос в код с минимальными правками.

Иногда я даже забиваю на тесты, потому что все равно проверяю запросы на тестовой базе. Ожидаю, что если кто-то исправит запрос, то проверит его тоже. Однако я всегда пишу тест, который выполнит запрос на пустой базе – чтобы убедиться, что нет ошибок синтаксиса.

Если в проекте используется ORM, то непонятно, как быть. Скажем, написал я запрос с группировкой и джоинами. От отлично работает. Как перенести его в ORM? Даже если я напишу цепочку методов, нужно проверить, что итоговый SQL выглядит как я хотел. Можно включить логирование запросов и посмотреть, что получилось, но способ сомнительный. Получается двойная работа: пишешь SQL, переносишь в объектную модель, подсматриваешь логи, правишь объекты и так по кругу.

Со временем я понял, что лучше сидеть на одном стуле, а не на двух. Поэтому – оставьте SQL в виде SQL. Любой человек скопирует его в PGAdmin и получит результат. Когда вместо SQL – каскад квери-билдеров, теряется та самая быстрая связь, о которой речь в начале. Все, она прервана, репл не работает, очередной радостью меньше.

Зачем так жить?