Rails PostgreSQL 更改数据库字段类型报错 ‘PG::DatatypeMismatch: ERROR: column xxx cannot be cast automatically to type integer’

chaz1942 · 2016年07月18日 · 最后由 kxu1988 回复于 2018年09月19日 · 5657 次阅读

刚才想更改数据库的字段类型 由 string 改为 integer, 刚开始这么写的

change_column :table_name, :column_name, :integer

报错

== 20160718031624 xxxxx: migrating ======================
-- change_column(:table_name, :column_name, :integer)
rake aborted!
StandardError: An error has occurred, this and all later migrations canceled:

PG::DatatypeMismatch: ERROR:  column "column_name" cannot be cast automatically to type integer
HINT:  You might need to specify "USING freight_calculation_rule_id::integer".

上面说需要配置"USING freight_calculation_rule_id::integer"

看了下源码

def change_column(table_name, column_name, type, options = {})
  clear_cache!
  quoted_table_name = quote_table_name(table_name)
  sql_type = type_to_sql(type, options[:limit], options[:precision], options[:scale])
  sql_type << "[]" if options[:array]
  sql = "ALTER TABLE #{quoted_table_name} ALTER COLUMN #{quote_column_name(column_name)} TYPE #{sql_type}"
  sql << " USING #{options[:using]}" if options[:using]
  if options[:cast_as]
    sql << " USING CAST(#{quote_column_name(column_name)} AS #{type_to_sql(options[:cast_as], options[:limit], options[:precision], options[:scale])})"
  end
  execute sql

  change_column_default(table_name, column_name, options[:default]) if options_include_default?(options)
  change_column_null(table_name, column_name, options[:null], options[:default]) if options.key?(:null)
end

将需要配置的 USING 放到 option[:using] 写成如下格式

change_column :shipping_area_freight_calculation_rules, :freight_calculation_rule_id, :integer, using: 'freight_calculation_rule_id::integer'

执行成功,一点小小的心得,希望能帮助到别人。 学习 rails 就像打怪升级,一不小心就解锁了隐藏技能

很有用,不知道为什么非要制定这个呢

kxu1988 回复

因为怕你丢数据

luikore 回复

了解了,谢谢

需要 登录 后方可回复, 如果你还没有账号请 注册新账号