如何打印postgres"提醒通知"续集输出?

时间:2017-05-17 14:39:46

标签: ruby postgresql sequel

提升通知通常用于调试postgres中的PSQL脚本(link)。

The docs say that there's some kind of support for printing notices when using the pg gem,但是没有关于如何使用此过程,它产生什么,可能(可能?)警告等的信息。

有没有人有生产和/或开发的工作代码示例?理想情况下,我正在寻找一种解决方案,允许在启用Sequel日志记录时打开PG通知。

当我这样做时:

DB = Sequel.connect(
  ENV['DATABASE_URL'],
  notice_receiver: lambda{ |x| binding.pry }
)

一旦我执行一个引发通知的函数,就永远不会调用notice_receiver lambda。即

[1] pry(#<Psql::CalculateMasterBalancesTest>)> DB.select{ |o| Sequel.function(:emit_notice) }.first
I, [2017-05-17T16:51:56.746003 #23139]  INFO -- : (0.000335s) SELECT emit_notice() LIMIT 1
=> {:emit_notice=>""}

发出通知的地方是:

CREATE OR REPLACE FUNCTION emit_notice()
  RETURNS VOID AS $$

BEGIN
  RAISE NOTICE 'NOTICE ME!!!';
END;
$$ LANGUAGE plpgsql;

它起作用于PgAdmin:

NOTICE:  NOTICE ME!!!
Total query runtime: 21 ms.
1 row retrieved.

更新

Alejandro C给出了一个很好的工作示例,似乎通知不会随notice_receiver挂钩分发。例如:

Sequel.connect(DB.opts.merge(:notice_receiver=>proc{|r| puts r.result_error_message})){ |db|
  db.do("BEGIN\nRAISE NOTICE 'foo';\nEND;")
}

什么都不打印,并且:

Sequel.connect(DB.opts.merge(:notice_receiver=>proc{|r| puts r.result_error_message})){ |db|
  db.do("BEGIN\nRAISE WARNING 'foo';\nEND;")
}

打印

  

警告:foo

Sequel just calls set_notice_receiver from PG以来,我想我应该向PG提交错误报告。

编辑2

然而,当我尝试使用PG宝石时,我得到了

conn = PG.connect( :dbname => 'db_test', user: 'test', password: 'test', host: '127.0.0.1' )
conn.set_notice_receiver{|r| puts r.result_error_message }
conn.exec("SELECT emit_notice()")
NOTICE:  NOTICE ME!!!
=> #<PG::Result:0x0000000405ac18 status=PGRES_TUPLES_OK ntuples=1 nfields=1 cmd_tuples=1>

所以在这一点上我有点困惑......

编辑3

Posted an issue GitHub...

编辑4

啊,显然还有其他需要使用的选项,client_min_messages需要设置为:notice,如下所示:

DB = Sequel.connect(
  ENV['DATABASE_URL'],
  notice_receiver: proc{|r| puts r.result_error_message},
  client_min_messages: :notice
)

这是有效的

1 个答案:

答案 0 :(得分:1)

你传入你自己的proc,它以字符串形式通知你。要让它在通知上触发而不是just warnings and above,请使用client_min_messages。例如:

a = nil
Sequel.connect(
  DB.opts.merge(
      notice_receiver: proc{|r| a = r.result_error_message}, 
      client_min_messages: :notice)) { |db|
  db.do("BEGIN\nRAISE WARNING 'foo';\nEND;")
}
a == "WARNING:  foo\n" # true