【问题标题】:Column does not exist error in PostgreSQL database and Rails 3 appPostgreSQL 数据库和 Rails 3 应用程序中的列不存在错误
【发布时间】:2013-01-30 05:39:39
【问题描述】:

我在尝试查询我的 PostgreSQL 数据库时收到以下错误。我可以在 pgAdmin 中查看表和所有列,甚至可以执行 select *,所以我知道表和列存在。对此的任何帮助将不胜感激。

这是我得到的错误:

PG::Error: ERROR:  column "fi_ase" does not exist

这是相关表的架构。它是作为 Rails 3.2 应用程序的一部分通过迁移生成的。

create_table "certificates", :force => true do |t|
  t.integer  "profile_id"
  t.boolean  "FI_ASE"
  t.boolean  "FI_AME"
  t.boolean  "FI_INSTA"
  t.datetime "created_at",    :null => false
  t.datetime "updated_at",    :null => false
  t.boolean  "C_ASEL"
  t.boolean  "C_AMEL"
  t.boolean  "C_ASES"
  t.boolean  "C_AMES"
  t.boolean  "ATP_ASEL"
  t.boolean  "ATP_AMEL"
  t.boolean  "ATP_ASES"
  t.boolean  "ATP_AMES"
  t.boolean  "GI_Basic"
  t.boolean  "GI_Advanced"
  t.boolean  "GI_Instrument"
end

这是我在 Rails 中的查询/方法:

def self.search(city, state, zip, *certs)
  query_obj = joins(:profile => [:addresses, :certificate])
  query_obj = query_obj.where("city like ?", "%#{city}%") unless city.blank?
  query_obj = query_obj.where("state = ?", state) unless state.blank?
  query_obj = query_obj.where("zip like ?", "%#{zip}%") unless zip.blank?
  query_obj = query_obj.where("FI_ASE = ?", true) unless certs[0].blank?

  query_obj
end

直接在我的 pgAmin SQL 编辑器中运行以下 SQL 语句时,我遇到了同样的错误:

select *
from contacts c
inner join profiles p on c.id = p.contact_id
inner join addresses a on p.id = a.profile_id
inner join certificates ct on p.id = ct.profile_id
where ct.FI_ASE = true

【问题讨论】:

  • 你能描述一下数据库表证书吗? "\d 证书"

标签: ruby-on-rails ruby-on-rails-3 postgresql ruby-on-rails-3.2


【解决方案1】:

Rails 在生成列名时会用双引号引起来。例如,当 PostgreSQL 看到它时,您的表的 CREATE TABLE 将如下所示:

create table "certificates" (
  -- ...
  "FI_ASE" boolean,

当一个标识符被双引号括起来时,它是区分大小写的。但是,PostgreSQL 会将不带引号的标识符规范化为小写,所以当你这样说时:

query_obj.where("FI_ASE = ?", true)

SQL 将显示为:

where FI_ASE = 't'

但是,由于您的 FI_ASE 没有被引用,PostgreSQL 会看到:

where fi_ase = 't'

但是,您的表没有fi_ase 列,它有一个FI_ASE 列。

既然我们知道出了什么问题,我们该如何解决呢?您可以一直手动引用列名:

where('"FI_ASE" = ?', true)

或者你可以让 ActiveRecord 来做(但要确保你使用正确的大小写):

where(:FI_ASE => true)

或者最重要的是,使用小写的列名重新创建表,这样您就不必引用内容了。

【讨论】:

  • 感谢您的深入解释!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-06-25
  • 1970-01-01
  • 2015-10-11
  • 1970-01-01
  • 2011-06-03
相关资源
最近更新 更多