Как отправить сообщение электронной почты из триггера PostgreSQL?
Я использую pgsql для установки триггера при обновлении набора данных таблицы (измените статус на "Готово" )
он автоматически отправит электронное письмо на учетную запись электронной почты с использованием значения электронной почты набора данных и сохранит это электронное письмо на сервере
но я не знаю, как писать в функции триггера для отправки электронной почты и отправлять электронную почту на сервере.
Заранее благодарю
Версия Pg - 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;
Ответы
Ответ 1
См. отличную статью как обычный depesz и pg-message-queue.
Отправка электронной почты непосредственно из базы данных может быть отличной идеей. Что делать, если разрешение DNS медленное, и все зависает в течение 30 секунд, а затем отключается? Что делать, если ваш почтовый сервер неустойчив и занимает 5 минут, чтобы принимать сообщения? Вы получите сеансы базы данных, зависающие в вашем триггере, пока вы не достигнете max_connections
, и вдруг вы не сможете ничего сделать, кроме как ждать или начинать ручную отмену транзакций.
То, что я рекомендую, имеет триггер NOTIFY
a LISTEN
ing helper script, который остается постоянно запущенным и подключен к БД (но не в транзакции).
Весь ваш триггер должен сделать INSERT
строку в таблицу очередей и отправить NOTIFY
. Ваш script получает сообщение NOTIFY
, потому что он зарегистрировался на LISTEN
для него, проверяет таблицу очередей и делает все остальное.
Вы можете написать вспомогательную программу на любом языке; Обычно я использую Python с psycopg2
.
То, что script может отправить электронное письмо на основе информации, найденной в базе данных. Вам не нужно делать все уродливое форматирование текста в PL/PgSQL, вместо этого вы можете заменить вещи на шаблон на более мощном языке сценариев и просто извлекать данные переменных из базы данных, когда приходит NOTIFY
.
При таком подходе ваш помощник может отправлять каждое сообщение и только затем удалять информацию из таблицы очередей. Таким образом, если в вашей почтовой системе возникают временные проблемы, которые приводят к сбою, вы не потеряли информацию и можете продолжать попытки отправить ее до тех пор, пока не добьетесь успеха.
Если вы действительно должны сделать это в базе данных, см. PgMail.
Ответ 2
- Используйте локальный MTA (это дает вам централизованную конфигурацию SMTP для нескольких приложений).
- Примените локальное реле MTA к вашему реальному MTA (это дает вам асинхронную поддержку, по существу)
- Если вы используете Windows, используйте blat SMTP-клиент командной строки. Убедитесь, что путь к blat находится в PATH
- Вам следует, вероятно, сделать это с помощью Apache Camel или pgAgent, а не напрямую в триггере
Это будет работать в Windows, если postgres superuser. Функция триггера должна быть ОПРЕДЕЛЕННОСТЬ БЕЗОПАСНОСТИ. Аналогично для sendmail в Linux:
...
copy
( select 'my email body' )
to program
'blat -to [email protected] -from [email protected] -subject "My Subject" -server localhost:25'
with (
format text
);
...
~ 60 мс
Ответ 3
Вы можете использовать plperlu для отправки почты.
Эта ссылка показывает пример использования триггера.
Ответ 4
У вас есть возможность использовать pgMail (если вам разрешено его устанавливать):
Если вы следуете инструкциям на brandolabs.com, оно сводится к
pgmail('Send From ','Send To ','Subject goes here','Message body here.')
Ответ 5
Я согласен с @Craig Ringer. Вы можете закодировать что-то в Python под 100 строками кода. Я бы рекомендовал использовать следующие библиотеки Python: psycopg2, smtplib. В зависимости от того, как часто вы хотите получать уведомления об изменениях, вы можете запустить cronjob (в зависимости от вашей рабочей среды). Таким образом, вы можете агрегировать несколько изменений в базе данных в один адрес электронной почты, а не отправлять уведомление каждый раз, когда происходит изменение.