pg gem:'警告:没有为类型"numeric"定义类型转换

And*_*nes 8 ruby postgresql

我无法从pg gem获取输入结果.

require 'pg'                                                            
require_relative 'spec/fixtures/database'                               

client = PG.connect( DB[:pg] )                                            
client.type_map_for_queries = PG::BasicTypeMapForQueries.new(client)    
client.type_map_for_results = PG::BasicTypeMapForResults.new(client)    

client.exec( %|select * from testme;| ) do |query|                        
  query.each {|r| puts r.inspect }                                      
end
Run Code Online (Sandbox Code Playgroud)

该程序给出了输出:

Warning: no type cast defined for type "money" with oid 790. Please cast this type explicitly to TEXT to be safe for future changes.
Warning: no type cast defined for type "numeric" with oid 1700. Please cast this type explicitly to TEXT to be safe for future changes.
{"string"=>"thing", "logical"=>true, "cash"=>"£1.23", "reel"=>"2.34", "day"=>#<Date: 2015-12-31 ((2457388j,0s,0n),+0s,2299161j)>, "float"=>3.45}
Run Code Online (Sandbox Code Playgroud)

所以:布尔值和浮点数和日期(和整数)被转换,但不是数字或金钱类型.

任何人都可以告诉我如何"明确地转换类型",假设我不想为每个表硬编码解决方案?

Jac*_*ack 5

劫持这个线程,经过一番挖掘,我终于找到了添加自定义解码器/编码器的方法,因此发布了一个示例:

require 'ipaddr'
require 'pg'

class InetDecoder < PG::SimpleDecoder
  def decode(string, tuple=nil, field=nil)
    IPAddr.new(string)
  end
end
class InetEncoder < PG::SimpleEncoder
  def encode(ip_addr)
    ip_addr.to_s
  end
end

# 0 if for text format, can also be 1 for binary
PG::BasicTypeRegistry.register_type(0, 'inet', InetEncoder, InetDecoder)
Run Code Online (Sandbox Code Playgroud)


小智 5

对于那些寻求默认转换字符串的人来说,这是一个全部内容:

client = PG.connect( DB[:pg] )           

map = PG::BasicTypeMapForResults.new(conn)
map.default_type_map = PG::TypeMapAllStrings.new

client.type_map_for_results = map
Run Code Online (Sandbox Code Playgroud)


小智 3

文本字段也有同样的问题。通过复制编码器并编辑其 OID 来解决。

text_coder = client.type_map_for_results.coders.find { |c| c.name == 'text' }
new_coder = text_coder.dup.tap { |c| c.oid = 19 } # oid from the warning
conn.type_map_for_results.add_coder(new_coder)
Run Code Online (Sandbox Code Playgroud)


我是如何到达那里的:如果问题相似但不相同,下一个人可能会感兴趣。

我在网上看到其他人谈论type_map_for_results,但他们不知道如何定义编码器。由于在我的例子中它是一个文本字段,因此我决定尝试克隆一个现有的文本字段。我知道我可以在 Rails 应用程序中找到文本预设,所以我打开rails console并搜索:

adapter = ActiveRecord::Base.connection
connection = adapter.instance_variable_get("@connection")
mapping = connection.type_map_for_results
cd mapping  # my console of choice is `pry`
ls          # spotted a likely getter named `coders`
cd coders   # again
ls          # spotted getter `name` and setter `oid=`
Run Code Online (Sandbox Code Playgroud)

所以我将解决方案中的代码放在一起。尝试了一下,结果成功了。

找到它并不容易,所以我决定退出潜伏者模式并在 SO 上分享它。因此:感谢@Andreyy带我进来:)

[撬开cdls]