如何在Go中监听Postgres存储过程触发器?

huangapple go评论129阅读模式
英文:

How do I listen to a Postgres stored procedure trigger from Go?

问题

在Postgres数据库中,我有一个可以通过以下方式触发的存储过程:

SELECT add_customer('name', 'lastname')

我希望从我的Go代码中监听这个触发器。

我尝试过以下方法:

  1. import (
  2. "github.com/jmoiron/sqlx"
  3. "github.com/lib/pq"
  4. )
  5. // 之前的代码..
  6. db, _ := sqlx.Connect("postgres", connStr)
  7. // 假设db已连接并正常工作
  8. minReconn := 10 * time.Second
  9. maxReconn := time.Minute
  10. listener := pq.NewListener(psqlInfo, minReconn, maxReconn, reportProblem)
  11. err = listener.Listen("add_customer")
  12. if err != nil {
  13. return nil, err
  14. }

在我的代码的main函数中,我调用一个等待通知的函数:

  1. go func() {
  2. somepackage.WaitForNotification()
  3. }()

函数的代码如下:

  1. func (k *someStruct) WaitForNotification() {
  2. select {
  3. // 这个case永远不会满足
  4. case notification := <-k.db.Listener.Notify:
  5. k.logger.Info(fmt.Sprintf("%v", notification))
  6. err := doWork()
  7. // ...
  8. }
  9. }

如注释所述,上述代码路径永远不会被执行。

根据文档搜索结果,存储过程与Postgres中的LISTEN/NOTIFY事件不同。

我该如何在Go中监听存储过程的触发?

英文:

In a Postgres database, I have a stored procedure that can be triggered as such:

SELECT add_customer(&#39;name&#39;, &#39;lastname&#39;)

I wish to listen to this trigger from my Go-code.

What I've tried:

  1. import (
  2. &quot;github.com/jmoiron/sqlx&quot;
  3. &quot;github.com/lib/pq&quot;
  4. )
  5. // Code beforehand..
  6. db, _ := sqlx.Connect(&quot;postgres&quot;, connStr)
  7. // Assume db is connected and works
  8. minReconn := 10 * time.Second
  9. maxReconn := time.Minute
  10. listener := pq.NewListener(psqlInfo, minReconn, maxReconn, reportProblem)
  11. err = listener.Listen(&quot;add_customer&quot;)
  12. if err != nil {
  13. return nil, err
  14. }

In main of my code, I call a function that waits for notifications:

  1. go func() {
  2. somepackage.WaitForNotification()
  3. }()

That looks like:

  1. func (k *someStruct) WaitForNotification() {
  2. select {
  3. // This case is never satisfied
  4. case notification := &lt;-k.db.Listener.Notify:
  5. k.logger.Info(fmt.Sprintf(&quot;%v&quot;, notification))
  6. err := doWork()
  7. // ...
  8. }
  9. }

As commented, the above code path is never reached.

Searching docs, it is evident that the stored procs are not the same as LISTEN/NOTIFY events in Postgres.

How do I listen to a stored procedure being triggered from Go?

答案1

得分: 1

更新你的add_customer函数,以便向频道发送通知。要发送通知,请使用NOTIFY命令或pg_notify(text, text)函数。

  1. CREATE OR REPLACE FUNCTION add_customer(first_name text, last_name text) RETURNS void
  2. LANGUAGE plpgsql STRICT
  3. AS $_$
  4. BEGIN
  5. NOTIFY add_customer, '<payload>';
  6. -- 或者
  7. SELECT pg_notify('add_customer', '<payload>');
  8. -- 其余的代码
  9. END
  10. $_$;
英文:

Update your add_customer function to send a notification to the channel. To send the notification use the NOTIFY command or the pg_notify(text, text) function.

  1. CREATE OR REPLACE FUNCTION add_customer(first_name text, last_name text) RETURNS void
  2. LANGUAGE plpgsql STRICT
  3. AS $_$
  4. BEGIN
  5. NOTIFY add_customer, &#39;&lt;payload&gt;&#39;;
  6. -- or
  7. SELECT pg_notify(&#39;add_customer&#39;, &#39;&lt;payload&gt;&#39;);
  8. -- the rest of your code
  9. END
  10. $_$;

huangapple
  • 本文由 发表于 2021年5月26日 14:47:34
  • 转载请务必保留本文链接:https://go.coder-hub.com/67699848.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定