Как я могу отправить письмо с триггера PostgreSQL?

Я использую pgsql для установки триггера, когда обновляю набор данных таблицы (изменяю статус на Законченный), он автоматически отправляет электронное письмо на учетную запись электронной почты, используя значение электронной почты набора данных, и сохраняет это письмо на сервере.

но я не знаю, как написать в триггерной функции для отправки электронной почты и отправки электронной почты на сервере. заранее спасибо

Версия для ПК 9.1, а CentOS 5.8

CREATE OR REPLACE FUNCTION sss()
RETURNS trigger AS
$BODY$begin
if(NEW.publisher== 'aaaa')
then
//send email and save to server 192.168.171.64
end if;
return NEW;
end

$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
ALTER FUNCTION sss()
OWNER TO postgres;
GRANT EXECUTE ON FUNCTION sss() TO postgres;

6 ответов

Решение

Смотрите отличную статью о depesz и pg-message-queue.

Отправка электронной почты непосредственно из базы данных не может быть хорошей идеей. Что если разрешение DNS медленное и все зависает на 30 секунд, а затем время ожидания? Что делать, если ваш почтовый сервер работает нестабильно и принимает сообщения за 5 минут? Вы будете зависать в сеансе базы данных, пока не достигнете max_connections и вдруг вы ничего не можете сделать, кроме как ждать или начать отмену транзакций вручную.

То, что я бы порекомендовал, это ваш триггер NOTIFY LISTEN вспомогательный скрипт, который постоянно работает и подключен к БД (но не в транзакции).

Все, что ваш триггер должен сделать, это INSERT строку в таблицу очередей и отправить NOTIFY, Ваш сценарий получает NOTIFY сообщение, потому что он зарегистрирован в LISTEN для этого проверяет таблицу очередей и делает все остальное.

Вы можете написать вспомогательную программу на любом удобном для вас языке; Я обычно использую Python с psycopg2,

Этот скрипт может отправить электронное письмо на основе информации, найденной в базе данных. Вам не нужно делать все уродливое форматирование текста в PL/PgSQL, вы можете вместо этого подставить элементы в шаблон на более мощном языке сценариев и просто получить переменные данные из базы данных, когда NOTIFY приходит в.

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

Если вы действительно должны сделать это в базе данных, смотрите PgMail.

  1. Используйте локальный MTA (это дает вам централизованную конфигурацию SMTP для нескольких приложений)
  2. Получите локальный MTA-ретранслятор на ваш настоящий MTA (по сути, это дает вам асинхронную поддержку)
  3. Если Windows, используйте клиента командной строки SMTP blat. Убедитесь, что путь к блату находится в ПУТИ
  4. Вы, вероятно, должны сделать это с помощью Apache Camel или pgAgent, а не напрямую в триггере.

Это будет работать на Windows, если postgres суперпользователь. Функция запуска должна быть ОПРЕДЕЛЕННОЙ БЕЗОПАСНОСТИ. Похоже на sendmail в Linux:

...

copy 
  ( select 'my email body' ) 
to program 
  'blat -to to@example.com -from from@example.com -subject "My Subject" -server localhost:25' 
with (
  format text
);

...

~ 60 мс

Вы можете использовать plperlu для отправки почты.

Эта ссылка показывает пример того, как использовать его на триггере.

У вас есть возможность использовать pgMail (если вам разрешено его устанавливать):

Если вы будете следовать инструкциям на сайте http://brandolabs.com/pgmail, все сводится к

pgmail('Send From ','Send To ','Subject goes here','Message body here.')

Я согласен с @Craig Ringer. Вы можете кодировать что-то в Python до 100 строк кода. Я бы порекомендовал использовать следующие библиотеки Python: psycopg2, smtplib. В зависимости от того, как часто вы хотите получать уведомления об изменениях, вы можете запустить cronjob (в зависимости от вашей рабочей среды). Таким образом, вы можете объединять несколько изменений в базе данных в одно электронное письмо, а не отправлять уведомление каждый раз, когда происходит изменение.

Если вы используете TypeScript/Node, используйте проверенную в боевых условиях базу кода graphile-worker для связи между Postgres и Node. Затем вы можете легко использовать стандартную логику электронной почты в Node для отправки электронной почты.

Другие вопросы по тегам