【问题标题】:MySQL Schema_Migrations - Active Record - Update ValuesMySQL Schema_Migrations - Active Record - 更新值
【发布时间】:2015-12-04 10:00:51
【问题描述】:

我们的旧版 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 个?

【问题讨论】:

  • 我不明白。为什么不直接在转储中删除迁移表并再次运行迁移?此外,如果您有很多迁移,则无需保留它们。无论如何,你永远不会回滚那么远。
  • 感谢您的建议。所以你是说我可以删除schema_migrations 表,重新运行迁移,它会正确地重新填充它?
  • 是的,如果您将所有之前的迁移都放在一个迁移文件中。但是再次查看您的代码似乎并非如此。

标签: mysql ruby-on-rails database activerecord


【解决方案1】:

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

干杯!

【讨论】:

  • 是的——这也是我的理解——所以我的问题更多是关于如何在MySQL终端中使用SQL来替换这些值!
  • 如果我理解正确,你不需要替换任何东西——你只需要插入新的迁移版本:INSERT INTO schema_migrations 'version' VALUES ('200507121201'), ('20151111084520'), ('20151117071001')
  • 感谢这个解决方案——正是我所需要的。 DELETE FROM schema_migrations; 后跟 INSERT INTO schema_migrations 'version' VALUES ('200507121201'), ('20151111084520'), ('20151117071001') 也适用于像我这样的其他 SQL 新手 INSERT INTO schema_migrations VALUES('200507121201'); 插入单个值。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多