Какой опыт работы с триггерными функциями в PostgreSQL
Что проверяют
Умеете ли вы решать, какую логику держать в базе, а какую в Python-коде, и знаете ли механику триггеров, а не только синтаксис CREATE TRIGGER. Следом обычно просят сравнить триггер с сигналом Django или событием SQLAlchemy.
Как отвечать
Начните с одного-двух случаев из практики: аудит изменений, updated_at, денормализованный счётчик, pg_notify для воркера на psycopg. Назовите свои цифры: объём таблицы, число триггеров, почему не в приложении. Если опыта нет, скажите прямо и покажите, что знаете устройство:
- функция и триггер раздельно: функция объявляется
RETURNS trigger, триггер привязывает её к таблице черезEXECUTE FUNCTION(староеEXECUTE PROCEDUREтоже работает); - BEFORE и AFTER: в
BEFORE ... FOR EACH ROWможно поправитьNEWили вернутьNULLи пропустить строку, вAFTERвозвращаемое значение игнорируется.INSTEAD OFбывает только на представлениях; - ROW и STATEMENT: построчный срабатывает на каждую строку, операторный один раз на запрос. Для массовых вставок у операторного есть transition tables через
REFERENCING NEW TABLE AS; - переменные:
TG_OP,TG_TABLE_NAME,OLD,NEW, а условиеWHENотсекает лишние срабатывания.
Главный довод за триггер: он срабатывает на любую запись, включая QuerySet.update(), bulk_create, ручной SQL и соседний сервис, а сигналы Django там молчат. Создавайте триггеры в миграциях Alembic или Django через RunSQL, чтобы они не жили только на проде.
Где спотыкаются
Забывают, что ORM не видит правок триггера. После save() у объекта в памяти старый updated_at, нужен refresh_from_db() или чтение через RETURNING.
Вешают на горячую таблицу триггер, который обновляет счётчик в одной строке. Все вставки начинают ждать блокировку этой строки.
Прячут в триггерах бизнес-логику, о которой команда не знает. Отладка превращается в поиск, кто поменял поле, и без документации это минус, а не плюс.