PostgreSQL、Rails + Heroku,Column 必须出现在“group by”中

发布于 2024-10-26 19:45:49 字数 2826 浏览 1 评论 0原文

当我在 Heroku 上部署应用程序时遇到此错误:

Started GET "/collections/transect/search?utf8=%E2%9C%93&search%5Btagged_with%5D=village&commit=Search" for 98.201.59.6 at 2011-03-27 17:02:12 -0700

ActionView::Template::Error (PGError: ERROR:  column "photos.custom_title" must appear in the GROUP BY clause or be used in an aggregate function
: SELECT  "photos".* FROM "photos" INNER JOIN "taggings" ON "photos"."id" = "taggings"."photo_id" INNER JOIN "tags" ON "tags"."id" = "taggings"."tag_id" WHERE "tags"."name" IN ('village') AND ("photos".collection_id = 1) GROUP BY photos.id LIMIT 20 OFFSET 0):
     17: 
     18: - @bodyclass = 'dark'
     19: #search_view.photo_tiles
     20:   = render :partial => 'collections/photos/alt_tiles', :collection => @photos, :as => :photo
   app/views/collections/search.html.haml:20:in `_app_views_collections_search_html_haml__2343730670144375006_16241280__2249843891577483539'

我看到了这些类似的问题(1, 2)。

问题是,此视图中没有任何内容要求 custom_title 属性,我也没有使用“group_by”子句执行查询。

这是似乎触发错误的部分:

- ((photo_counter+1) % 5 == 0) ? @class = 'last' : @class = ''
.photo{ :class => @class }
  .alt_tile
    = link_to( image_tag(photo.file.url(:tile)), collection_photo_path(@collection,photo), :class => 'img_container' )
    .location= photo.location(:min)
    .tags= photo.tag_array.join(' | ')

这是引发错误的 collections#search 操作:

def search
  @curator_toolbar = true
  @collection = Collection.find(params[:id])
  @search = @collection.photos.search(params[:search])
  @photos = @search.page(params[:page]).per(20)
end

所以看起来这可能是一个插件问题?我使用 MetaSearch 来实现搜索功能,使用 Kaminari 来实现分页。有谁对具体导致此问题的原因以及我如何解决它有任何想法或建议?

--编辑--

好的,我似乎找到了真正的问题:

使用 MetaSearch 与我的关键字标签模型,我创建了一个如下所示的搜索方法:

def self.tagged_with( string )
  array = string.split(',').map{ |s| s.lstrip }
  joins(:tags).where('tags.name' => array ).group('photos.id')
end

现在,我在创建此方法时得到了很多帮助 - 如我之前提到过我是一个彻头彻尾的 SQL 白痴。

此方法适用于 SQLite,但不适用于 PostgreSQL,因为每当搜索中包含关键字时,就会触发“group_by”问题。

所以,在这个问题 这似乎表明我需要将属于我的照片模型一部分的每一列放入“group”参数中,否则 Postgre 将崩溃。

这让我感到震惊有几个原因:

  1. 我的照片模型非常复杂并且有很多字段。
  2. 我的应用程序仍在开发中,照片模型的变化比其他任何应用程序都多。
  3. 如果将来有人忘记将列添加到标签搜索参数的组语句中,我不希望每次有人触摸照片模型时都会破坏我的代码。

那么,任何人都可以帮助我理解如何重写这个方法,这样它就不会破坏 PostgreSQL —— 理想情况下,这样我就不必在解决方案中包含属于该模型的所有字段的列表,或者在至少不是手动维护的列表?

I'm getting this error when I deploy my app on Heroku:

Started GET "/collections/transect/search?utf8=%E2%9C%93&search%5Btagged_with%5D=village&commit=Search" for 98.201.59.6 at 2011-03-27 17:02:12 -0700

ActionView::Template::Error (PGError: ERROR:  column "photos.custom_title" must appear in the GROUP BY clause or be used in an aggregate function
: SELECT  "photos".* FROM "photos" INNER JOIN "taggings" ON "photos"."id" = "taggings"."photo_id" INNER JOIN "tags" ON "tags"."id" = "taggings"."tag_id" WHERE "tags"."name" IN ('village') AND ("photos".collection_id = 1) GROUP BY photos.id LIMIT 20 OFFSET 0):
     17: 
     18: - @bodyclass = 'dark'
     19: #search_view.photo_tiles
     20:   = render :partial => 'collections/photos/alt_tiles', :collection => @photos, :as => :photo
   app/views/collections/search.html.haml:20:in `_app_views_collections_search_html_haml__2343730670144375006_16241280__2249843891577483539'

I saw these similar questions (1,2).

The problem is, nothing in this view is asking for the custom_title attribute, nor am I executing a query with a "group_by" clause.

Here's the partial that seems to trigger the error:

- ((photo_counter+1) % 5 == 0) ? @class = 'last' : @class = ''
.photo{ :class => @class }
  .alt_tile
    = link_to( image_tag(photo.file.url(:tile)), collection_photo_path(@collection,photo), :class => 'img_container' )
    .location= photo.location(:min)
    .tags= photo.tag_array.join(' | ')

Here's the collections#search action which is what raised the error:

def search
  @curator_toolbar = true
  @collection = Collection.find(params[:id])
  @search = @collection.photos.search(params[:search])
  @photos = @search.page(params[:page]).per(20)
end

So it looks like maybe this is a plugin issue? I'm using MetaSearch for search functionality and Kaminari for pagination. Does anyone have any ideas or suggestions as to what would cause this specifically and how I can possibly fix it?

--EDIT--

Ok, I seem to have found the real problem:

Using MetaSearch with my keyword tags model, I created a search method that looks like this:

def self.tagged_with( string )
  array = string.split(',').map{ |s| s.lstrip }
  joins(:tags).where('tags.name' => array ).group('photos.id')
end

Now, I was given a lot of help in creating this method -- as I mentioned before I'm a total SQL moron.

This method works on SQLite but not on PostgreSQL because whenever keywords are included in a search it triggers the "group_by" problem.

So, in this question it seems to indicate that I need to put every column that is part of my photo model in the "group" argument or Postgre will break.

That horrifies me for several reasons:

  1. My photo model is pretty complex and has a ton of fields.
  2. My app is still in development and the photo model changes more than any other.
  3. I don't want to have my code breaking every time someone touches the photo model in the future if they forget to add the columns to the group statement on the tag searching argument.

So, can anyone help me understand how to rewrite this method so that it won't break PostgreSQL -- and ideally so that I won't have to include a list of all the fields that belong to this model in the solution, or at least not a manually maintained list?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

欲拥i 2024-11-02 19:45:49

因此,事实证明我可以通过在 tagged_with 方法中将“group”替换为“select”来解决这个问题。

def self.tagged_with( string )
  array = string.split(',').map{ |s| s.lstrip }
  select('distinct photos.*').joins(:tags).where('tags.name' => array )
end

问题解决了! 请参阅这篇文章,了解为什么这是一个更好的主意。(抱歉,网站后来被删除,我不记得它说了什么。)另外,感谢 Mark Westling 回答了一个解决了我的问题的衍生问题。

So, it turns out I could solve this problem by replacing "group" with "select" in my tagged_with method.

def self.tagged_with( string )
  array = string.split(',').map{ |s| s.lstrip }
  select('distinct photos.*').joins(:tags).where('tags.name' => array )
end

Problem solved! See this article for a great explanation as to why this is a better idea anyway. (Sorry, web site was removed later on and I don't recall what it said.) Also, thanks to Mark Westling for his answer on a spinoff question that solved my problem.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文