gpt4 book ai didi

ruby-on-rails - 将 postgres ENUM 与 rails 一起使用会产生 `PG::DatatypeMismatch`

转载 作者:行者123 更新时间:2023-11-29 12:03:56 24 4
gpt4 key购买 nike

尝试更新 Postgres ENUM 列的值会抛出以下异常:

ActiveRecord::StatementInvalid Exception: PG::DatatypeMismatch: ERROR: column "interesting_column" is of type interesting_thing but expression is of type integer

LINE 1: UPDATE "interesting_table" SET "interesting_column" = 0, "updated_a...

HINT: You will need to rewrite or cast the expression.

InterestingTable.first.update_attributes!(normal_column: 'food')
# => perfectly fine
InterestingTable.first.update_attributes!(interesting_column: 'foo')
# => above exception

这是创建表的迁移:

class CreateInterestingTables < ActiveRecord::Migration
def up
execute <<-SQL
CREATE TYPE normal_thing AS ENUM ('food', 'water', 'shelter');
CREATE TYPE interesting_thing AS ENUM ('foo', 'bar', 'baz');
SQL

create_table :interesting_tables do |t|
t.column :normal_column, :normal_thing
t.column :interesting_column, :interesting_thing
end
end

def down
drop_table :interesting_tables
execute 'DROP TYPE normal_thing'
execute 'DROP TYPE interesting_thing'
end
end

最佳答案

问题在于,虽然该列在数据库中具有正确的类型,但 Active Record 会尝试将其解释为 integer。您可以通过运行来验证:

InterestingTable.columns
# => [#<ActiveRecord::ConnectionAdapters::PostgreSQLColumn:0x007f7567f82260
# @coder=nil,
# @default=nil,
# @limit=nil,
# @name="id",
# @null=false,
# @precision=nil,
# @primary=true,
# @scale=nil,
# @sql_type="integer",
# @type=:integer>,
# #<ActiveRecord::ConnectionAdapters::PostgreSQLColumn:0x007f7568075690
# @coder=nil,
# @default=nil,
# @limit=nil,
# @name="normal_column",
# @null=true,
# @precision=nil,
# @primary=false,
# @scale=nil,
# @sql_type="normal_thing",
# @type=nil>,
# #<ActiveRecord::ConnectionAdapters::PostgreSQLColumn:0x007f7568075668
# @coder=nil,
# @default=nil,
# @limit=nil,
# @name="interesting_column",
# @null=true,
# @precision=nil,
# @primary=false,
# @scale=nil,
# @sql_type="interesting_thing",
# @type=:integer>]

请注意第二列的类型是 nil,而最后一列的类型是 integer。如果您的字符串不是以数字开头,String#to_i 将返回 0,因此您会收到试图分配 0 的错误。


但这是为什么呢?原因 - interesting_thing 包含子字符串 int,适配器认为它是一个 integer。这似乎是一个长期存在的错误,直到 rails 4.2 才得到修复。 The offending method.


可能的解决方案:

  • 迁移到 rails 4.2+
  • 将您的 ENUM 重命名为不匹配的名称
  • Monkey 修补适配器。这是一个quick fix .

关于ruby-on-rails - 将 postgres ENUM 与 rails 一起使用会产生 `PG::DatatypeMismatch`,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38110923/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com