由于我的开发环境默认设置为sqllite3,因此我遇到了将rails代码部署到Heroku的一些问题。这是以下日志快照:
ActiveRecord::StatementInvalid (PG::Error: ERROR: syntax error at or near ":"
2012-05-25T14:11:55+00:00 app[web.1]:
2012-05-25T14:11:55+00:00 app[web.1]: LINE 1: ...LECT "records".* FROM "records" WHERE (TIMESTAMP(:order) >=...
2012-05-25T14:11:55+00:00 app[web.1]: : SELECT "records".* FROM "records" WHERE (TIMESTAMP(:order) >= '2011-05-25 00:00:00' and TIMESTAMP(:order) <= '2012-05-25 23:59:59') ORDER BY created_at):
2012-05-25T14:11:55+00:00 app[web.1]: app/controllers/records_controller.rb:20:in `index'
我的控制器文件中的代码片段:
opts = {:order => "created_at"}
opts[:conditions] = (@start_date.nil? ? "" : "TIMESTAMP(created_at::text) >= '#{@start_date.to_s(:db)}'")
opts[:conditions] += ((@start_date.nil? || @end_date.nil?) ? "" : " and ")
opts[:conditions] += (@end_date.nil? ? "" : "TIMESTAMP(created_at::text) <= '#{@end_date.to_s(:db)}'")
最初,我有一个“DATETIME”,你有TIMESTAMP,所以我切换它仍然遇到问题。这段代码的上下文是我在日期之间运行查询,格式如下:2011-05-25 00:00:00
答案 0 :(得分:1)
您的created_at
应该已经timestamp
,因此TIMESTAMP(created_at::text)
无需尝试将其投放到timestamp
;无论如何,timestamp(x)
将无法在PostgreSQL中运行。你不应该为SQLite提供那种东西。
您最终会像这样运行SQL:
SELECT "records".*
FROM "records"
WHERE TIMESTAMP(:order) >= '2011-05-25 00:00:00'
and TIMESTAMP(:order) <= '2012-05-25 23:59:59'
ORDER BY created_at
你正在做一些在SQL中将created_at::text
更改为:order
的地方。我无法重现这种行为,但我怀疑你正在与命名占位符(即column = :value
而不是column = ?
)发生冲突,但这只是一个疯狂的猜测。
在任何情况下,如果摆脱timestamp(...)
内容并转而关联where
来电,您将获得更好的内容:
query = Record.order(:created_at)
query = query.where('created_at >= ?', @start_date) if(@start_date.present?)
query = query.where('created_at <= ?', @end_date) if(@end_date.present?)
然后您可以query.all
或query.paginate(...)
或其他任何方式获得最终结果。那就是(恕我直言)比一堆字符串争吵更漂亮,它应该在任何地方都一样。
如果您要在PostgreSQL(即Heroku)之上进行部署,那么您应该在PostgreSQL之上进行开发和测试。 SQLite对SQL是什么以及它的类型系统如何工作有一些奇怪的想法,PostgreSQL(幸运的是)更不宽容。您应始终在同一堆栈上进行开发和部署,相同一直应用到版本号。