Rails 3 迁移现在在 rails 5 中失败
Rails 3 migration now fail in rails 5
我有这个迁移,我将一个列从整数转换为一个字符串数组。
class ChangeWdayFromIntegerToStringInResourceWeekDayStart < ActiveRecord::Migration[4.2]
def up
change_column :resource_week_day_starts, :wday, :string, default: []
add_column :resource_week_day_starts, :number_days, :integer, default: 7
end
def down
change_column :resource_week_day_starts, :wday, :string, default: nil
change_column :resource_week_day_starts, :wday, 'integer USING CAST(wday AS integer)'
remove_column :resource_week_day_starts, :number_days
end
end
当我们在 rails 3 时,此迁移工作得很好,但我们已经迁移到 rails 5,现在我们尝试设置一个新服务器。当 运行 在 rails 5 中迁移时,我们收到此错误消息:
PG::DatatypeMismatch: ERROR: column "wday" cannot be cast automatically to type character varying[]
HINT: You might need to specify "USING wday::character varying[]".
: ALTER TABLE "resource_week_day_starts" ALTER COLUMN "wday" TYPE character varying[]
/home/ruby/src/mapsbooking/db/migrate/20170307000000_change_wday_from_integer_to_string_in_resource_week_day_start.rb:3:in `up'
我已经尝试了很多方法来解决这个问题。但是没有任何效果。
谁能帮帮我
谢谢
您遇到三个问题:
- 正如 max 在评论中所说,您需要在选项中包含
array: true
以便获得数组列。
- 您需要一个 SQL 表达式来将单个整数转换为字符串数组,以便您可以在 ALTER TABLE.
中包含合适的 USING 子句
change_column
想分别更改类型和默认值。
(1)很简单,在change_column
选项中添加array: true
。
(2) 有点难,但我想到了几个选项。您可以使用 element-to-array concatenation operator 和类型转换:
wday::varchar || array[]::varchar[]
::
是类型转换,||
是串联运算符,array[]
是空数组。或者,如果标点符号太多,您可以使用 array_append
函数来做同样的事情:
array_append(array[]::varchar[], wday::varchar)
(3) 可以通过在 change_column
.
之前调用 change_column_default
来删除旧的默认值来处理
将它们放在一起:
change_column_default :resource_week_day_starts, :wday, nil
change_column :resource_week_day_starts,
:wday,
:string,
array: true,
default: [],
using: 'array_append(array[]::varchar[], wday::varchar)'
如果您目前有 nulls in
wday`,这可能会在 wday
中留下 array[null]
个值。如有必要,您可以在之后清理它们。
我有这个迁移,我将一个列从整数转换为一个字符串数组。
class ChangeWdayFromIntegerToStringInResourceWeekDayStart < ActiveRecord::Migration[4.2]
def up
change_column :resource_week_day_starts, :wday, :string, default: []
add_column :resource_week_day_starts, :number_days, :integer, default: 7
end
def down
change_column :resource_week_day_starts, :wday, :string, default: nil
change_column :resource_week_day_starts, :wday, 'integer USING CAST(wday AS integer)'
remove_column :resource_week_day_starts, :number_days
end
end
当我们在 rails 3 时,此迁移工作得很好,但我们已经迁移到 rails 5,现在我们尝试设置一个新服务器。当 运行 在 rails 5 中迁移时,我们收到此错误消息:
PG::DatatypeMismatch: ERROR: column "wday" cannot be cast automatically to type character varying[]
HINT: You might need to specify "USING wday::character varying[]".
: ALTER TABLE "resource_week_day_starts" ALTER COLUMN "wday" TYPE character varying[]
/home/ruby/src/mapsbooking/db/migrate/20170307000000_change_wday_from_integer_to_string_in_resource_week_day_start.rb:3:in `up'
我已经尝试了很多方法来解决这个问题。但是没有任何效果。
谁能帮帮我
谢谢
您遇到三个问题:
- 正如 max 在评论中所说,您需要在选项中包含
array: true
以便获得数组列。 - 您需要一个 SQL 表达式来将单个整数转换为字符串数组,以便您可以在 ALTER TABLE. 中包含合适的 USING 子句
change_column
想分别更改类型和默认值。
(1)很简单,在change_column
选项中添加array: true
。
(2) 有点难,但我想到了几个选项。您可以使用 element-to-array concatenation operator 和类型转换:
wday::varchar || array[]::varchar[]
::
是类型转换,||
是串联运算符,array[]
是空数组。或者,如果标点符号太多,您可以使用 array_append
函数来做同样的事情:
array_append(array[]::varchar[], wday::varchar)
(3) 可以通过在 change_column
.
change_column_default
来删除旧的默认值来处理
将它们放在一起:
change_column_default :resource_week_day_starts, :wday, nil
change_column :resource_week_day_starts,
:wday,
:string,
array: true,
default: [],
using: 'array_append(array[]::varchar[], wday::varchar)'
如果您目前有 nulls in
wday`,这可能会在 wday
中留下 array[null]
个值。如有必要,您可以在之后清理它们。