Ruby on rails 在rails 3.2中,回滚迁移将列类型从字符串更改为文本,其中db是postgresql

Ruby on rails 在rails 3.2中,回滚迁移将列类型从字符串更改为文本,其中db是postgresql,ruby-on-rails,ruby-on-rails-3,postgresql,Ruby On Rails,Ruby On Rails 3,Postgresql,我已经了解了在使用postgresql和rails 3.2时将列类型从字符串更改为文本的解决方案。我也实施了它。但当我回滚此迁移时,它会失败,并出现“PG::StringDataRightTruncation:ERROR:value-too-long”错误。我们应该如何解决这个问题?您的新值对于旧类型来说太长了。如果值超过255个字符,PostgreSQL将不得不丢弃数据以更改为varchar(255)。它拒绝这样做,因为如果没有得到非常明确的通知,它不会导致数据丢失 如果您不介意截断这些长值,

我已经了解了在使用postgresql和rails 3.2时将列类型从字符串更改为文本的解决方案。我也实施了它。但当我回滚此迁移时,它会失败,并出现“PG::StringDataRightTruncation:ERROR:value-too-long”错误。我们应该如何解决这个问题?

您的新值对于旧类型来说太长了。如果值超过255个字符,PostgreSQL将不得不丢弃数据以更改为
varchar(255)
。它拒绝这样做,因为如果没有得到非常明确的通知,它不会导致数据丢失

如果您不介意截断这些长值,永久且不可恢复地丢弃数据,您可以使用
ALTER COLUMN的
USING
子句。。。键入
。这与将字符串列转换为整数时使用的方法相同

ALTER TABLE mytable 
  ALTER COLUMN mycolumn 
  TYPE varchar(255) 
  USING (substring(mycolumn from 1 for 255));
我不认为有任何方法可以在Rails迁移中对称地表达这一点;向上迁移和向下迁移需要单独的子句,向上迁移是一个简单的过程:

ALTER TABLE mytable 
  ALTER COLUMN mycolumn 
  TYPE text;

坦率地说,我认为在迁移中这样做是一个可怕的想法。迁移应该失败。此操作需要管理员干预,以更新数据过长的列,然后运行迁移。

?PostgreSQL中没有“字符串”类型。如果您正在从
varchar
转换为
text
,那么它就不会被截断。你是不是想换个方向?@CraigRinger我是说PostgreSQL中的varchar,字符串是在迁移中使用后指定的。无疑,向上迁移工作正常,但向下迁移失败。需要一个向下迁移(即回滚)的解决方案。这正是需要的。感谢您的快速帮助。将管理干预与alter表分开的问题在于运行迁移需要时间。如果您可以冻结系统,这没有问题。但在活动的迁移中,在完成管理任务和执行迁移之间,有人可以输入一个长度超过允许字符串的新值,这将导致迁移失败。@kikito很好。您需要在此处将约束添加为
无效
,进行更改,并
更改
约束以将其标记为
有效
并更改类型,但不幸的是,PostgreSQL目前仅支持
无效
外键
约束。您必须使用触发器来强制执行长度限制。有点混乱,所以如果您能够承受停机时间,那么在一次迁移中完成它是有意义的。