0

自从我的开发环境默认设置为 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

4

1 回答 1

1

created_at应该已经是 atimestamp所以没有必要TIMESTAMP(created_at::text)尝试将它转换为 a 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.allquery.paginate(...)以其他方式获得最终结果。那(恕我直言)比一堆字符串争吵要漂亮得多,它应该在任何地方都一样。

如果您打算在 PostgreSQL(即 Heroku)上进行部署,那么您应该在 PostgreSQL 上进行开发和测试。SQLite 对 SQL 是什么以及它的类型系统如何工作有一些奇怪的想法,PostgreSQL(谢天谢地)不那么宽容。您应该始终在同一个堆栈上开发和部署,并且一直适用于版本号。

于 2012-05-25T16:25:41.060 回答