MySQL Schema_Migrations - 活动记录 - 更新值

时间:2015-12-04 10:00:52

标签: mysql ruby-on-rails database activerecord

我们的旧版Rails应用程序有一些破坏的迁移(因此我们将迁移转移到了一个大型迁移中),为它编写了一个rake任务并且一切都很好。

desc "Removes all schema migrations and inserts the migration reconstruction"
 task reconstruct_migrations: :environment do
   reconstruction_migration = Dir["db/migrate/*.rb"].find { |migration| migration =~ /reconstruct_database/ }
   file_name = reconstruction_migration.split("/").last
   timestamp = file_name.split("_").first

   puts ">> Resetting migration version to #{timestamp}"

   ActiveRecord::Base.transaction do
     ActiveRecord::Base.connection.tap do |c|
       c.execute("DELETE FROM schema_migrations")
       c.execute("INSERT INTO schema_migrations(version) VALUES ('#{timestamp}')")
     end
  end
end

这有点不正统,但它是大型遗留应用程序,这就是情况。但是,即使在重建迁移后,运行新迁移时也会失败,因为现有的MySQL转储会有一个冲突的schema_migrations表。它的版本列包含所有先前的迁移时间戳,如下所示:

+----------------+
| version        |
+----------------+
| 20081121002510 |
| 20081124055648 |
| 20081124102955 |
| 20081124103008 |
etc....

要修复我的情况,我需要使用rails应用中的当前时间戳覆盖此版本列的值。这些是:

200507121201
20151111084520
20151117071001

表格:

mysql> show columns from schema_migrations;
+---------+--------------+------+-----+---------+-------+
| Field   | Type         | Null | Key | Default | Extra |
+---------+--------------+------+-----+---------+-------+
| version | varchar(255) | NO   | PRI | NULL    |       |
+---------+--------------+------+-----+---------+-------+
1 row in set (0.00 sec)

我尝试对此问题进行排序:

 mysql> UPDATE `schema_migrations` SET `version` = '';
 ERROR 1062 (23000): Duplicate entry '' for key 'unique_schema_migrations'


 mysql> alter table schema_migrations drop column version;
 ERROR 1090 (42000): You can't delete all columns with ALTER TABLE; use DROP TABLE instead

总结如何总结如何覆盖此列中的现有值并将其替换为上面列出的3?

1 个答案:

答案 0 :(得分:0)

所以看起来你需要在schema_migrations中保留所有现有的迁移版本,因为下次运行rake db:migrate时Rails会查找它们。基本上,如果我得到正确的答案,您唯一需要做的就是将重建迁移的时间戳添加到schema_migrations

干杯!