Pg gem: "Warning: type type defined for type" numeric ",

I am having trouble getting printed results from pg pearls.

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 

This program displays the result:

 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} 

So: booleans and float and dates (and integers) are converted, but not numerical values ​​or money type.

Can someone tell me how to "explicitly type in", assuming I don’t want to hard code the solution for each table?

+7
ruby postgresql
source share
3 answers

Got the same problem with the text box. Solved by duplicating the encoder and editing its 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) 



How did I get there: this may interest the next guy if the problem is similar, but not identical.

I read other people on the net talking about type_map_for_results , but how they didn’t know how to determine the encoder. Since this was a text box in my case, I decided to try cloning an existing one. I knew that I could find the Rails text preinstalled application, so I opened the rails console and searched for:

 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=` 

So, I put together the code in the solution. Tried it and it worked.

It was not easy to find, so I decided to exit lurker mode and share it with SO. Thereby: thanks @Andreyy for me :)

[ pry cd and ls ]

+1
source share

Capturing this topic, as after some digging, I finally found a way to add a custom decoder / encoder, so posting an example below:

 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) 
+2
source share
  • Google will receive an error message: "Warning: type type specified for type"
  • You can find it by github source.
  • When re-classing, I would suggest that lines from 150 to 214 can be combined Examples:
    • register_type 0, 'text', PG::TextEncoder::String
    • alias_type 0, 'varchar', 'text'
  • Since register_type and alias_type are methods of the PG::BasicTypeRegistry::CoderMap , I would play with them simply and see that something will change:
    • PG::BasicTypeRegistry::CoderMap.alias_type 0, 'money', 'text'
    • PG::BasicTypeRegistry::CoderMap.alias_type 0, 'numeric', 'text'

Reading comments in the class it seems that encoding / decoding of these and some other fields is not implemented.

You might want to use a higher level ORM library, such as AvtiveRecord, which implements more types ( money ).

0
source share

All Articles