Rails:如何回滚错误的迁移?

15

我是个白痴...在Rails中搞砸了一次迁移:

以为迁移会像模型生成器一样工作(使用references:modelname),我做了以下操作:

$ rails g migration add_event_to_photos references:event

创建了迁移的

class AddEventToPhotos < ActiveRecord::Migration
  def change
    add_column :photos, :references, :event
  end
end

现在,我的开发数据库(SQLite3)在photos表中有一个类型为eventreferences列。

而且我的schema.rb文件中间有一行代码:

# Could not dump table "photos" because of following StandardError
#   Unknown type 'event' for column 'references'

rake db:rollback 无法解决这个问题:

$ rake db:rollback
==  AddEventToPhotos: reverting ===============================================
-- remove_column("photos", :references)
rake aborted!
An error has occurred, this and all later migrations canceled:

undefined method `to_sym' for nil:NilClass

那么,如何回滚并保留数据库中的开发数据?如果必须这样做,我甚至可以清空照片表,但不想重新构建整个项目。该怎么办?


顺便说一句 - 对于任何打算犯同样愚蠢错误的人...不要这么做!请使用正确的迁移生成器:

$ rails g migration add_event_to_photos event_id:integer
5个回答

6
我发现最简单的方法是在 /db/ 目录下的 schema.rb 文件中重新创建表。之后运行 rake db:reset 命令(如果出现未完成迁移的情况,请删除它们并重试)。
这样就解决了问题。

3

使用./script/rails dbconsole进入数据库。然后输入以下命令:

.output dump.sql
.dump

在文件dump.sql中,您将找到用于重新创建和填充数据库的SQL命令。请使用您喜欢的编辑器(例如vim ;-))编辑它,删除或修复列类型。您还可以从schema_migrations表中删除无效的迁移标识符。删除您的数据库(我建议只重命名db/development.sqlite文件),创建新的数据库并将转储文件读入其中(使用命令.read dump.sql)。
现在,您只需要修复并运行迁移即可。

2

添加一个空的down方法并运行rake db:rollback。

编辑,那是新的迁移语法,你可以将body替换为:

def self.down; end

你可以选择使用旧的语法,或者直接删除整个代码块(我没有尝试过),然后运行rake db:rollback


这似乎将回滚计数器(或跟踪迁移的任何内容)向后移动一个,但它保留了数据库中类型为“event”的references列,这会阻止schema.rb更新,因为它“无法转储表”照片”...” - Meltemi
啊,这比我想象的要复杂。现在,既然模式号已经回滚,你能否直接从schema.rb中删除这些行呢? - numbers1311407
是的。但据我所知,我无法运行 rake db:schema:load,因为模式已经混乱了... - Meltemi
你可以进入SQLite并删除照片表,然后创建一个临时迁移来重建照片表并运行它。只需将原始照片表定义复制到新生成的迁移中即可。 - numbers1311407
SQLite3中好像没有drop的功能...至少我不知道有这个功能。 - Meltemi

1

这只是一个想法,我知道它不特定于SQLite,你可以回滚到旧版本的模式,然后重新加载。从那里再试一次?您可以在GIT中还原(checkout)特定文件。然后执行def self.down; end,如另一位发帖者所建议的那样。


0
问题出在SQLite可以使用任何给定的类型(在本例中是event)来创建模式,但无法将该类型转回ActiveRecord。您需要编辑sqlite_master文件并更改create table字符串(sql),以使其正确。如果您错误地操作此字符串,则可能会破坏表格,因此最好先备份表格。这里有一个相关的Rails问题

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接