2

我正在一个遗留数据库上构建一个 Rails 3.2 应用程序,该数据库在不同的表中也有一些损坏的记录。最令人头疼的问题之一是它包含无效日期。

我设置了一个沙箱,我手动修复了一次以使我的代码正常工作。现在是部署的时候了。出于这个原因,沙箱每晚都会重置并从实时数据库中复制,重新构建 ferret 索引,并重新应用迁移。我们将经常部署到沙箱,以便在部署到实时设置之前进行最后的修复。

由于旧的 PHP 应用程序和这个新的 Rails 应用程序需要并行运行几周到几个月,我们不能简单地一次性修复日期(更新:只是为了澄清,这意味着它们同时在同一个数据库上运行时间)。我需要一种方法来自动化这个,也许是迁移或 rake 任务(我会选择后者)。

但问题是:ActiveRecord 无法加载此类记录,因此我无法通过 ruby​​ 代码中的一些硬编码假设来调查记录并修复日期。

第二个问题是遗留数据库存在不一致,因为 PHP 代码没有使用事务,并且一些代码路径被破坏,留下孤立和破坏的表约束。我会在它们发生时处理它们,其中大部分已经在模型中得到处理。第一个问题与日期有关。

你通常会如何解决这个问题?也许甚至还有一些神奇的宝石,它支持通过拦截异常和运行一些尝试修复代码来迁移记录损坏的遗留数据库......

迁移路径使用 MySQL 和三个生产环境(使用实时数据库的稳定环境、使用相同数据库的暂存环境以及每晚重置数据库克隆的沙箱)。我们决定不进行一次性数据映射/迁移,因为我们无法一步替换完整的遗留应用程序(它由一个包含大约 50000 篇文章、数百个主题、包含图像和下载的巨大文件数据库的 CMS 组成,支持大约 10 个网站,大约 12 年的数据和工作,来自不同编程技能的凌乱 PHP 代码,来自不同迁移阶段的重复代码,从合作伙伴站点提取 RSS 内容以将那里的文章/帖子混合到我们自己应用程序主题中的文章时间线中,以及更多有趣的东西...

第一步是迁移后端应用程序以获得一致的管理和发布界面。遗留的前端应用程序仍然需要写入数据库(访问者创建的评论和其他内容)。因此,修复数据库的过程必须能够定期在无人​​值守的情况下运行。

我们已经修复了可以优雅地处理 belongs_to 和 has_many 中损坏的模型依赖关系的修复程序。回形针集成旨在与发明的所有奇妙的文件名映射一起使用。airbrake gem 会向我们的 redmine 安装报告所有应用程序崩溃,因此我们可以快速了解所有剩余的怪癖。

旧版应用程序已经过修改以使用最新的 MySQL 版本,并已迁移到当前的 MySQL 数据库服务器。

4

4 回答 4

3

我有同样的问题。解决方案是告诉 mysql2 不要执行强制转换,如下所示:

client.query(sql, cast: false).each do |row|
  row['some_date'] = Date.parse(row['some_date']) rescue(nil)
end

有关如何构建客户端对象的详细信息,请参阅mysql2 文档。如果需要,请通过ActiveRecord::Base.configurations.

于 2014-08-20T23:52:55.867 回答
0

类似于:Rails:如何处理数据库中现有的无效日期?而且也没有正确答案,所以我在下面重新发布我的解决方案。

我认为对我有用的最简单的解决方案是在database.yml文件中设置 write cast: false,例如用于开发部分

development
  <<: *default
  adapter: mysql2    
  (... some other settings ...)
  cast: false
于 2014-12-08T03:24:03.473 回答
0

创建一个数据导入 rake 任务,该任务执行您需要的所有转换和修复(包括数据解析和修复),并在每次从旧版应用程序获得新更新时运行它。该任务可以使用原始 SQL(查找“execute”和“exec_query”方法),它不必使用模型。这将是您正在寻找的神奇“宝石”。显然,你不可能有一个万能的工具,因为每个损坏数据的案例都是独一无二的。但只是不要在你的新代码库中创建kludges。

于 2013-05-06T05:35:15.087 回答
-1

我相信它会解决你的问题Date.parse()

例如 Date.parse(foo.created_at)

于 2013-05-06T02:09:23.390 回答