1

我正在使用 mysql 开发我的应用程序,但我使用 Heroku 来部署它并被迫使用 PG。

我对以下语句有疑问:

<% current_user_savings = Saving.where{user_id == my{current_user}} %>      

<% @latest_savings =  Saving.where{product_id.not_in(current_user_savings.select{product_id})}.group{product_id} %>

所以它可以在我的电脑上运行,但是在部署到 heroku 时,我遇到了以下问题:

ActionView::Template::Error (PGError: ERROR:  column "savings.id" must appear in the GROUP      BY clause or be used in an aggregate function
LINE 1: SELECT "savings".* FROM "savings"  WHERE "savings"."product_...
SELECT "savings".* FROM "savings"  WHERE "savings"."product_id" NOT IN (SELECT "savings"."product_id" FROM "savings"  WHERE "savings"."user_id" = 1) GROUP BY "savings"."product_id"):

我真的不知道如何解决这个问题并让它在heroku上工作。

请求的 Gemfile:来源 'https://rubygems.org'

ruby '1.9.3'
gem 'rails', '3.2.7'
gem 'compass_twitter_bootstrap', '2.0.3'
gem 'bcrypt-ruby', '3.0.1'
gem 'faker', '1.0.1'
gem 'will_paginate', '3.0.3'
gem 'bootstrap-will_paginate', '0.0.6'
gem 'omniauth-facebook', '1.4.0'
gem 'railroady'
gem 'devise', '2.1.2'
gem 'devise_invitable'
gem 'simple_form'
gem "mongoid", "~> 3.0.0"
gem 'thin'
gem 'best_in_place'
gem "jquery-fileupload-rails"
gem 'paperclip'
gem "squeel"
gem 'client_side_validations'
gem 'wicked'
gem 'koala'
gem 'aws-sdk'
gem 'bson_ext'


group :development, :test do
    gem 'sqlite3'
end
group :development, :test do
    gem 'annotate', '2.5.0'
end

group :test, :development do
    gem 'rspec-rails'
end

group :assets do
  gem 'sass-rails',   '~> 3.2.3'
  gem 'compass-rails', '1.0.3'
  gem 'coffee-rails', '~> 3.2.1'
  gem 'uglifier', '>= 1.0.3'
end

gem 'jquery-rails'
gem 'jquery-ui-rails'

group :test do
    gem 'capybara'
    gem 'factory_girl_rails'
end

group :production do
    gem 'pg', '0.12.2'
end 
4

4 回答 4

1

我认为其中一些代码属于范围或至少属于您的控制器。但除此之外,您可以发布您的 Gemfile 吗?

在我看来,最好的做法是在开发中使用相同的数据库和 ORM。您是否尝试过在本地运行 PG?

看起来这里可能发生了一些让你很难过的事情,首先让 PG 在你的开发机器上本地运行,然后更新你databases.yml的同步。

其次,你也在使用 MongoBD 吗?如果您不再使用它,可能会从捆绑包中删除它。

我稍微清理了您的 Gemfile 以使其更易于阅读,但我建议将 gem 分组为更好地代表 gem 在项目中的角色的部分,我喜欢记录每个 gem,以便清楚它的作用,通常,rails 应用程序倾向于以巨大的 Gemfile 结尾,这使得获取其他人的项目变得非常困难:

source 'https://rubygems.org'
ruby '1.9.3'

gem 'rails', '3.2.7'

gem 'compass_twitter_bootstrap', '2.0.3'
gem 'bcrypt-ruby', '3.0.1'
gem 'faker', '1.0.1'
gem 'will_paginate', '3.0.3'
gem 'bootstrap-will_paginate', '0.0.6'
gem 'omniauth-facebook', '1.4.0'
gem 'railroady'
gem 'devise', '2.1.2'
gem 'devise_invitable'
gem 'simple_form'
gem 'best_in_place'
gem "jquery-fileupload-rails"
gem 'paperclip'
gem "squeel"
gem 'client_side_validations'
gem 'wicked'
gem 'koala'
gem 'aws-sdk'

gem 'pg', '0.12.2'

gem 'jquery-rails'
gem 'jquery-ui-rails'

group :development, :test do
    gem 'annotate', '2.5.0'
    gem 'rspec-rails'
end

group :test do
    gem 'capybara'
    gem 'factory_girl_rails'
end

group :assets do
  gem 'sass-rails',   '~> 3.2.3'
  gem 'compass-rails', '1.0.3'
  gem 'coffee-rails', '~> 3.2.1'
  gem 'uglifier', '>= 1.0.3'
end

最后,查看您的application.rb,并确保 ActiveRecord 可用,这似乎是必须的,但看看,您可能require "rails/all"在顶部附近的某个地方。

于 2012-10-30T19:35:40.750 回答
1

GROUP BY当用户从 MySQL 迁移到 PostgreSQL 时,这是一个已知的痛点

正如@rs 所指出的,您的 SQL 有点问题。

如果您按主键分组

假设这savings.product_id是主键,因为这是此查询正确的唯一方法,它依赖于数据库知道按主键分组隐式分组所有字段,因为主键是唯一的。

MySQL 不知道,它只是继续并为每个字段选择它看到的第一个结果。在这种情况下,这是正确的,因为您是按主键分组的,但在其他情况下很容易产生不可预测的结果。

PostgreSQL 9.0 及更低版本承认按主键分组意味着您已经对所有字段进行了分组,尽管 SQL-99 标准要求它这样做。这些版本要求您SELECTGROUP BY. 这很笨拙,因此您可以做的最好的事情是升级到不再受此限制的 PostgreSQL 9.1 或 9.2

由于您使用的是查询生成器,因此处理这个问题变得更加复杂。您不能只修改您的 SQL。如果你不能升级 PostgreSQL,你需要弄清楚如何让你的查询生成器相信GROUP BY表中的所有列。

如果您按其他字段分组

如果savings.product_id不是主键,那么您的查询就是完全错误的。SELECT您必须在列表中列出您想要的每个字段GROUP BY以保证唯一且明确的结果,或者仅引用聚合函数中的字段。

MySQL 无论如何都会执行这个查询,但它依赖于你知道结果是明确的。如果一个字段有多个可能的值,它只会选择它首先得到的任何一个。

在这种情况下,很难弄清楚您的查询实际上应该做什么以及您期望从中得到什么结果。

于 2012-10-31T00:11:01.667 回答
1

谢谢大家的帮助,我最终做到了,它正在本地的 PG 上工作!

Saving.select("DISTINCT ON (savings.product_id) * ").where{product_id.not_in(current_user_savings.select{product_id})}.group("savings.user_id, savings.updated_at, savings.id, savings.product_id, savings.price,savings.wishlist_id, savings.saved, savings.created_at")

遇到这个问题让我在 dev 中将我的 db 从 mysql 切换到 pg,所以在 heroku 中不再感到惊讶!

于 2012-11-01T10:55:23.167 回答
0

您的 SQL 将无法在 PG 中运行,MySQL 将允许您这样做,但任何其他 DBMS 都不允许

这个查询:

SELECT "savings".* FROM "savings"  
WHERE "savings"."product_id" 
NOT IN (SELECT "savings"."product_id" FROM "savings"  
         WHERE "savings"."user_id" = 1) 
GROUP BY "savings"."product_id"

应该

SELECT "savings"."product_id", count(*) FROM "savings"  
--change this to your AGGR func
WHERE "savings"."product_id" 
NOT IN (SELECT "savings"."product_id" FROM "savings"  
         WHERE "savings"."user_id" = 1) 
GROUP BY "savings"."product_id"
于 2012-10-30T18:16:08.373 回答