Как стать автором
Обновить

Комментарии 12

Благодарю! Спер копию в локальный Joplin.

Давно примеряюсь перенести продукт с MS SQL Server на PostgreSQL.

В SQL Server использую SQL CLR в триггерах, где сложная логика написана на C-sharp.
В частности, есть простая, но очень удобная функция отсылки HTTP запроса, что позволяет SQL серверу из триггера Push Notification на дальнейшую сложную обработку вместо Periodic Pull через интервалы времени.

А как проще всего реализовать HTTP GET/POST в триггере на PostgreSQL?

А как проще всего реализовать HTTP GET/POST в триггере на PostgreSQL?

Вызвать pg_curl (в pg_task, если надо асинхронно)

а как там с обработкой ошибок если запрос занял много времени? А таких запросов много?

Я лет несколько не смотрел но как бы себе блокировку не создать? Или если оно умеет порождать отдельный процесс, то форк бомбу?

Если что я не настоящий сварщик, простой мимокрокодил

Параметр на timeout

Для асинхронной обработки в SQL Server есть несколько стандартных механизмов "из коробки": диспетчер задач (SQL agent), события (create event notification и extended events), брокер (Service Broker).
Создание триггеров на C# CLR - нерекомендуемая практика, язык Transact SQL достаточно развит, а триггеры поддерживают обработку всего набора данных за один проход. Если вдруг вы уперлись в сложность вычислений, то это верный признак для выноса обработки из СУБД на клиентов (сервисы)
Прежде чем планировать миграцию, попытайтесь достичь той же производительности и стоимости поддержки, если это является критерием в вашей организации.

  • AFTER триггеры полезны для действий, которые зависят от конечного состояния данных (например, логирование).

Логирование вообще-то требует обоих триггеров.

BEFORE - логирует намерение. Действие (пользователя). Причём логирование должно выполняться в нетранзакционное хранилище, чтобы информация не откатилась при ошибке транзакции. Кстати, а Postgress так умеет?

AFTER - логирует результат реализации этого намерения, если запрос не привёл к ошибке.

логирование должно выполняться в нетранзакционное хранилище, чтобы информация не откатилась при ошибке транзакции. Кстати, а Postgress так умеет?

с расширением https://github.com/omniti-labs/pg_jobmon

То есть "из коробки" такой возможности не имеется?

К слову, а как себя ведёт COPY TO, если файл назначения существует? дописывает? перезаписывает? генерирует ошибку? нет у меня сейчас постгресса, на котором можно было бы попробовать, а официальная документация этот момент как-то стыдливо обходит... Если файл дописывается, то вот оно, нетранзакционное хранилище...

Если писать COPY TO напрямую в файл, то он будет перезаписываться

Чтобы сделать append, можно:

  • направить COPY TO в STDOUT и перенаправлять STDOUT в целевой файл

  • направить COPY TO в PROGRAM

copy (select * from table) to PROGRAM 'cat >>/tmp/log.txt'

Логирование можно делать через автономные транзакции с помощью встроенного расширения dblink (есть из коробки) - можно писать логи в ту же БД, можно писать в другие БД на том же или другом кластере PostgreSQL

Ну или любым из FDW для сброса логов в другие типы хранилищ

Мощь Postgress в красивой реализации триггеров уровня STATEMENT

PostgreSQL поддерживает как per-row triggers, так и per-statement triggers:

On tables and foreign tables, triggers can be defined to execute either before or after any INSERTUPDATE, or DELETE operation, either once per modified row, or once per SQL statement.

Однако о втором типе триггеров в статье - ни полслова. Что, с моей точки зрения, очень плохо. Особенно с учётом того, что триггерные функции у этих типов триггеров просто обязаны различаться. Да и эффективность у этих типов триггеров различна, причём далеко не в пользу per-statement типа.

Зарегистрируйтесь на Хабре, чтобы оставить комментарий