2011-12-23 86 views
1

我只是试图运行查询来查找数据库中的所有记录在“datetime”列中的值小于当前的unix时间戳。活动记录查询和heroku问题。

目前这是我的代码。它在当地运行良好。

t = Time.new.to_i 
Event.where("datetime < #{t}") 

当我在heroku控制台中测试这个错误时,我得到这个错误。

>> Event.where("datetime < #{t}") 
ActiveRecord::StatementInvalid: PGError: ERROR: operator does not exist: character varying < integer 
LINE 1: SELECT "events".* FROM "events" WHERE (datetime < 132462148... 
                 ^
HINT: No operator matches the given name and argument type(s). You might need to add explicit type casts. 
: SELECT "events".* FROM "events" WHERE (datetime < 1324621488) 
    /app/.bundle/gems/ruby/1.9.1/gems/activerecord-3.1.1/lib/active_record/connection_adapters/postgresql_adapter.rb:1003:in `async_exec' 
    /app/.bundle/gems/ruby/1.9.1/gems/activerecord-3.1.1/lib/active_record/connection_adapters/postgresql_adapter.rb:1003:in `exec_no_cache' 
    /app/.bundle/gems/ruby/1.9.1/gems/activerecord-3.1.1/lib/active_record/connection_adapters/postgresql_adapter.rb:591:in `block in exec_query' 
    /app/.bundle/gems/ruby/1.9.1/gems/activerecord-3.1.1/lib/active_record/connection_adapters/abstract_adapter.rb:244:in `block in log' 

任何想法?

+0

你在本地使用postgresql吗? – thatmiddleway 2011-12-23 06:40:19

回答

5

你应该使用placeholder得到正确的格式,并确保它被正确引用:

t  = Time.new 
events = Event.where("datetime < :t", :t => t) 

您不能timestamp列在PostgreSQL的整数比较,但你可以在SQLite的。您必须将您的timestamp与另一个timestamp(或date)或可以解析为timestamp的字符串进行比较。这个SQL将无法正常工作:

SELECT "events".* FROM "events" WHERE (datetime < 132462148) 

但这些将:

SELECT "events".* FROM "events" WHERE (datetime < '2011-12-23 06:52:25.096869') 
SELECT "events".* FROM "events" WHERE (datetime < '2011-12-23') 

这里有几个教训:

  1. 你也应该开始,如果你对PostgreSQL的顶部发展将部署到Heroku,ActiveRecord不会使您免受各种数据库之间的所有差异的困扰。
  2. 你应该让ActiveRecord尽可能地担心类型转换的问题,如果你正在比较一个日期或时间,使用占位符并且手工处理某种时间对象,让AR担心它。
  3. 尽可能使用占位符而不是字符串插值。
+0

谢谢。这解决了我的问题! – Jon 2011-12-23 07:49:51