Есть ли возможность экстренно узнавать что в БД PostgreSQL появилась запись?

Есть система которая, которая имеет django-бэкенд, некий фронтэнд, базу данных Postgres и плагин, который сохраяет некие сообщения в БД от mqtt-брокера.

Так вот, от брокера (плагина) в базе данных сохраняются сообщения не только статистики от датчиков, но и сообщения об ошибках, которые имеют критический характер. Возможно ли из БД отправлять сигнал, что появилась запись в базе данных с критическим характером? Или каким то другим образом отлавливать данные сообщения? Задача такая, чтобы пробросить эти сообщения до фронтэнда и при отключеном клиенте от web-портала отсылать ему почту или смс (здесь не так важен функционал).

Т.е. спрашивать периодически базу о таких сообщениях конечно можно, но система достаточно большая и включает в себя порядка 20к датчиков.

UPD: в комментариях было предложено использовать NOTIFY/LISTEN. Есть ли другие решения или технологии?


Ответы (3 шт):

Автор решения: Inventor

Первое от чего стоит отталкиваться это то, что БД ни при каких обстоятельствах не может сама инициировать подключение. Всё общение с БД происходит по принципу: один запрос пользователя - один ответ от БД. Соответственно никакой сигнал или что-то ещё она вам отправлять не будет ни при каких обстоятельствах. Это говорит о том, что дальше будет 2 пути развития:

  1. Самый тупой и лёгкий. Периодическая задача, которая скажем, выполняется раз в минуту и проверяет не появилось ли в БД чего нового. Это приводит к тому, что появляется лишняя нагрузка на БД и мы тратим лишние ресурсы. Так же это происходит не моментально.

  2. Самое правильное решение. О том, что появилась новая запись мы должны узнать не от БД, а от того, кто её вставил. Ваш плагин должен отправить вам "сигнал" о том, что он вставил новую запись. Готового решения нет, оно индивидуально под каждый проект и пишется самостоятельно.

Я описал лишь доставку сообщения от БД (или того кто вставляет в БД) до бэка. Доставка сообщений от бэка до фронтенда осуществляется с помощью websocket. Django один из худших вариантов для websocket, как и все другие синхронные решения. Посмотрите на асинхронные фреймворки (например fastapi, вряд ли вы найдёте что-то лучше в питоне)

→ Ссылка
Автор решения: Barmaley

Эммм..., а что нельзя создать триггер в Postgres, который вызывает процедуру, типа:

CREATE TRIGGER on_insert
    INSTEAD OF INSERT ON my_table
    FOR EACH ROW
    EXECUTE PROCEDURE on_insert_row();

Ну а далее рученьками написать хранимку (on_insert_row()), благо у Postgres богато с этим.

Люди аж СМСки шлют - пример

→ Ссылка
Автор решения: asanisimov

В дополнение приведу вариант с брокером (На примере Apache Kafka), можно настроить коннекторы для чтения определенной таблицы. Не работал с MQTT, но судя по документации там тоже есть коннекторы ODBC.

Если в кратце:

  1. вы подключаете коннектор на чтение на определенную таблицу(да хоть на много таблиц) и указываете в какие топики(да-да, можно писать сразу в несколько топиков) отправлять данные + прочие настройки.
  2. На стороне бека отдельной задачей в селери/отдельным потоком/отдельным микросервисом/и тд и тп что больше нравится, подписываетесь на нужные топики, и при получении сообщения выполняете необходимые действия.
→ Ссылка