[英]connection.select_value only returns strings in postgres with pg gem
I'm converting a rails app from using mysql (mysql2 gem) to postgres (pg gem).我正在将 Rails 应用程序从使用 mysql (mysql2 gem) 转换为 postgres (pg gem)。
With mysql, ActiveRecord::Base.connection.select_value
calls return values typed according to the data, for example:使用mysql,
ActiveRecord::Base.connection.select_value
调用返回值根据数据键入,例如:
> ActiveRecord::Base.connection.select_value("SELECT COUNT(*) FROM errors")
=> 86
> ActiveRecord::Base.connection.select_value("SELECT exception FROM errors where id=565")
=> "TechTalk.Genome.SqlExecutionException"
> ActiveRecord::Base.connection.select_value("SELECT id FROM errors where id=565")
=> 565
However, with postgres, connection.select_value
always returns a string:但是,对于 postgres,
connection.select_value
总是返回一个字符串:
> ActiveRecord::Base.connection.select_value("SELECT COUNT(*) FROM errors")
=> "1"
> ActiveRecord::Base.connection.select_value("SELECT id FROM errors")
=> "1"
> ActiveRecord::Base.connection.select_value("SELECT source FROM errors limit 1")
=> "webapp"
This broke a few unit tests, and while those are fixable, I'm certain we have other code relying on these return values.这破坏了一些单元测试,虽然这些是可以修复的,但我确信我们还有其他代码依赖于这些返回值。 Is there a way to get properly-typed return values from
connection.select_value
when using postgres?有没有办法在使用 postgres 时从
connection.select_value
获取正确类型的返回值?
The short answer is no.最简洁的答案是不。 The 'pg' driver intentionally provides as thin a layer as possible on top of the native 'libpq' driver.
“pg”驱动程序有意在本机“libpq”驱动程序之上提供尽可能薄的层。 It doesn't do typecasting, as that's the responsibility of higher-level libraries that have some insight into the domain in which the results will be used.
它不进行类型转换,因为这是更高级别的库的责任,这些库对将使用结果的域有一些了解。 The rationale for this decision is documented on the PostgreSQL Wiki , and I'd be happy to discuss it with you further on the mailing list .
这个决定的理由记录在 PostgreSQL Wiki 上,我很乐意在邮件列表中与您进一步讨论。
For those who land here looking for an activerecord attributes (Rails) specific answer: I've done some tests ( https://gist.github.com/gamov/8fe38733012931eb3360 ) and discovered that:对于那些在这里寻找 activerecord 属性(Rails)特定答案的人:我做了一些测试( https://gist.github.com/gamov/8fe38733012931eb3360 )并发现:
RequestedItem.where(id: 1).select(*, 10 AS tq).first.tq.class
returns a String with Rails < 4 and a Fixnum with Rails >= 4.返回 Rails < 4 的 String 和 Rails >= 4 的 Fixnum。
The Postgres adapter will forward the types from the DB to the Persistence module so casting can be done transparently. Postgres 适配器会将类型从 DB 转发到 Persistence 模块,以便可以透明地进行转换。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.