我的活动记录模型PaperTrail::Version
有一个名为whodunnit
的字段,类型为text
。
我想对此字段进行where.not
查询:
PaperTrail::Version.where.not(:whodunnit => 4)
这在SQLite上工作正常,但如果在PostgreSQL上失败:
2014-12-04T07:21:42.484139+00:00 app[web.1]: ActionView::Template::Error (PG::UndefinedFunction: ERROR: operator does not exist: character varying <> integer
2014-12-04T07:21:42.484142+00:00 app[web.1]: LINE 1: ....("versions"."whodunnit" != 4) ORD...
我应该如何更改我的查询以使其在两个数据库上都有效?
看起来 SQLite 正在隐式地将varchar
转换为您的integer
。Postgres不会这样做,以减少意外数据丢失/意外行为的机会。
在 Postgres 中,您可以使用 ::<type>
从integer
显式转换为varchar
,反之亦然。(尽管从上面的错误来看,您的 Postgres 模型似乎将其作为 text
类型,这是特定于 Postgres 的,尽管在许多方面它的行为类似于varchar
。
我怀疑在没有特殊大小写的情况下执行此操作的最直接方法是将4
转换为字符串,我希望 Rails 随后会生成更兼容的 SQL。
所以,像这样:
PaperTrail::Version.where.not(:whodunnit => 4.to_s)
Postgres 在尝试将其应用于查询之前不会将给定的整数更改为字符串。只需将 4 更改为"4"即可解决问题。
PaperTrail::Version.where.not(:whodunnit => '4')
我刚才继续在我的本地系统上对此进行了测试,它使用 Postgres 9.3.5 将整数传递到查询中。您使用的是哪个版本?