如何从 PostgreSQL 触发器发送电子邮件?
Posted
技术标签:
【中文标题】如何从 PostgreSQL 触发器发送电子邮件?【英文标题】:How can I send email from PostgreSQL trigger? 【发布时间】:2012-08-13 17:13:04 【问题描述】:我在更新表数据集时使用 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;
【问题讨论】:
在询问有关 Pg 的问题时,解释一下您的设置非常有帮助,尤其是您的 Pg 版本。不同的版本有不同的功能,所以版本可能会影响答案。 【参考方案1】:请参阅 the excellent-as-usual depesz article 和 pg-message-queue。
直接从数据库发送电子邮件可能不是一个好主意。如果 DNS 解析很慢并且一切都挂起 30 秒然后超时怎么办?如果您的邮件服务器出现问题并需要 5 分钟 来接收邮件怎么办?您将在触发器中挂起数据库会话,直到您位于 max_connections
并且突然间您只能等待或开始手动取消事务。
我的建议是让您的触发器NOTIFY
LISTEN
ing 帮助脚本保持永久运行并连接到数据库(但不在事务中)。
您的触发器所要做的就是将INSERT
一行放入队列表并发送NOTIFY
。您的脚本会收到 NOTIFY
消息,因为它已为它注册到 LISTEN
,检查队列表,然后完成其余的工作。
您可以用任何方便的语言编写帮助程序;我通常将 Python 与 psycopg2
一起使用。
该脚本可以根据它在数据库中找到的信息发送电子邮件。您不必在 PL/PgSQL 中进行所有难看的文本格式化,您可以用更强大的脚本语言将内容替换为模板,并在 NOTIFY
出现时从数据库中获取变量数据。
通过这种方法,您的助手可以发送每条消息,然后才从队列表中删除信息。这样,如果您的邮件系统出现暂时性问题导致发送失败,您不会丢失信息,并且可以继续尝试发送,直到成功为止。
如果您确实必须在数据库中执行此操作,请参阅PgMail。
【讨论】:
@JesseSiu 您似乎复制并粘贴了您一小时前在另一个答案上发布的另一条评论。此答案与 PL/Perl 无关,出于我的答案中解释的原因,我不建议您使用它。使用在数据库外部运行的脚本发送邮件。 @JesseSiu 如果您不理解上述建议,或者它对您不起作用,请随时解释或要求澄清,我很乐意提供帮助。我只是认为你采取了错误的方法。 我实际上专门写了 pg-message-queue,所以这将是这个问题的答案。【参考方案2】:-
使用本地 MTA(这为您提供了多个应用程序的集中式 SMTP 配置)
让本地 MTA 中继到您的真实 MTA(这实质上为您提供了异步支持)
如果是 windows,请使用 blat SMTP 命令行客户端。确保 blat 的路径在 PATH 中
您可能应该使用 Apache Camel 或 pgAgent 执行此操作,而不是直接在触发器中
如果 postgres 超级用户,这将在 Windows 上运行。触发函数应该是 SECURITY DEFINER。 Linux 上的 sendmail 类似:
...
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 毫秒
【讨论】:
这正是我一直在寻找的解决方案,“编程”太糟糕了,仅在 PostgreSQL 9.3 之后才可用。【参考方案3】:您可以使用 plperlu 发送邮件。
This 链接显示了如何在触发器上使用它的示例。
【讨论】:
谢谢,但是语言是 plpgsql,当我输入时使用 Mail :: Sendmail;它显示语法错误 @JesseSiu 您必须以超级用户身份CREATE LANGUAGE plperlu;
才能使用它,并使用LANGUAGE 'plperlu';
。
当我输入 createlang plperlu mydb。它说无法打开扩展控制文件。在扩展文件夹中,它不包含 plperlu.control 文件?我该怎么办
@JesseSiu 这完全取决于您如何安装 PostgreSQL。两天前当我要求您添加您的 Pg 版本时,您仍然没有更新您的答案。也许你应该这样做,并解释你正在使用什么操作系统以及你是如何安装 Pg 的?一旦获得该信息,有人可能会帮助您。
对不起,我忘记添加信息了。 pg版本为9.1,CentOS 5.8【参考方案4】:
你可以使用 pgMail(如果你被允许安装的话):
如果您按照brandolabs.com 上的说明进行操作,则归结为
pgmail('Send From ','Send To ','Subject goes here','Message body here.')
【讨论】:
不安装 pgmail 可以用其他方式吗? 您可以使用它(安装程序)或使用下面帖子中的 plperlu 程序。【参考方案5】:我同意@Craig Ringer 的观点。你可以用 Python 编写不到 100 行代码的东西。我建议使用以下 Python 库:psycopg2、smtplib。根据您希望收到更改通知的频率,您可以运行 cronjob(取决于您的工作环境)。这样,您可以将数据库的多项更改汇总到一封电子邮件中,而不是每次发生更改时都发送通知。
【讨论】:
【参考方案6】:如果您使用 TypeScript/Node,则使用久经考验的 graphile-worker codebase 从 Postgres 到 Node 进行通信。然后,您可以轻松地使用 Node 中的标准电子邮件逻辑来发送电子邮件。
【讨论】:
以上是关于如何从 PostgreSQL 触发器发送电子邮件?的主要内容,如果未能解决你的问题,请参考以下文章