Есть ли возможность экстренно узнавать что в БД PostgreSQL появилась запись?
Есть система которая, которая имеет django-бэкенд, некий фронтэнд, базу данных Postgres и плагин, который сохраяет некие сообщения в БД от mqtt-брокера.
Так вот, от брокера (плагина) в базе данных сохраняются сообщения не только статистики от датчиков, но и сообщения об ошибках, которые имеют критический характер. Возможно ли из БД отправлять сигнал, что появилась запись в базе данных с критическим характером? Или каким то другим образом отлавливать данные сообщения? Задача такая, чтобы пробросить эти сообщения до фронтэнда и при отключеном клиенте от web-портала отсылать ему почту или смс (здесь не так важен функционал).
Т.е. спрашивать периодически базу о таких сообщениях конечно можно, но система достаточно большая и включает в себя порядка 20к датчиков.
UPD: в комментариях было предложено использовать NOTIFY/LISTEN. Есть ли другие решения или технологии?
Ответы (3 шт):
Первое от чего стоит отталкиваться это то, что БД ни при каких обстоятельствах не может сама инициировать подключение. Всё общение с БД происходит по принципу: один запрос пользователя - один ответ от БД. Соответственно никакой сигнал или что-то ещё она вам отправлять не будет ни при каких обстоятельствах. Это говорит о том, что дальше будет 2 пути развития:
Самый тупой и лёгкий. Периодическая задача, которая скажем, выполняется раз в минуту и проверяет не появилось ли в БД чего нового. Это приводит к тому, что появляется лишняя нагрузка на БД и мы тратим лишние ресурсы. Так же это происходит не моментально.
Самое правильное решение. О том, что появилась новая запись мы должны узнать не от БД, а от того, кто её вставил. Ваш плагин должен отправить вам "сигнал" о том, что он вставил новую запись. Готового решения нет, оно индивидуально под каждый проект и пишется самостоятельно.
Я описал лишь доставку сообщения от БД (или того кто вставляет в БД) до бэка. Доставка сообщений от бэка до фронтенда осуществляется с помощью websocket. Django один из худших вариантов для websocket, как и все другие синхронные решения. Посмотрите на асинхронные фреймворки (например fastapi, вряд ли вы найдёте что-то лучше в питоне)
Эммм..., а что нельзя создать триггер в Postgres, который вызывает процедуру, типа:
CREATE TRIGGER on_insert
INSTEAD OF INSERT ON my_table
FOR EACH ROW
EXECUTE PROCEDURE on_insert_row();
Ну а далее рученьками написать хранимку (on_insert_row()), благо у Postgres богато с этим.
Люди аж СМСки шлют - пример
В дополнение приведу вариант с брокером (На примере Apache Kafka), можно настроить коннекторы для чтения определенной таблицы. Не работал с MQTT, но судя по документации там тоже есть коннекторы ODBC.
Если в кратце:
- вы подключаете коннектор на чтение на определенную таблицу(да хоть на много таблиц) и указываете в какие топики(да-да, можно писать сразу в несколько топиков) отправлять данные + прочие настройки.
- На стороне бека отдельной задачей в селери/отдельным потоком/отдельным микросервисом/и тд и тп что больше нравится, подписываетесь на нужные топики, и при получении сообщения выполняете необходимые действия.