【问题标题】:How to handle periodically changing database data in your Rails app?如何处理 Rails 应用程序中定期更改的数据库数据?
【发布时间】:2011-06-07 00:35:12
【问题描述】:

编辑:为了清楚起见,我完全重写了这个问题。我之前没有得到任何cmets,也没有答案。

我正在维护一个包含大量统计数据的 2.x Rails 应用程序。有些数据是真实的,有些是未来几年的估计数据。每年我都需要用真实数据更新估计数据并计算新的估计值。

我每年都使用 BIG yml 文件和迁移将数据加载到应用程序中。我的迁移充满了估计计算和数据更正。


问题

我的迁移充满了与模式无关的材料,我什至无法梦想不等待几个小时就执行 db:migrate:reset(如果它甚至可以工作的话)。我很想看到我的迁移又好又干净——只有与架构相关的修改。但是,如果不使用迁移,我应该如何每年更新数据?


需要帮助

我想听听你的 cmets 和答案。我不是在寻找灵丹妙药——更像是人们如何处理类似情况的最佳实践和想法。

【问题讨论】:

  • 嗯,也许我应该尝试编辑这个问题。这很乱。即使我不想回答这个问题。好吧,我为此获得了 Tumbleweed 徽章 :)
  • 为了清楚起见,我完全重写了这个问题。任何 cmets 和答案都非常感谢!
  • 感谢您的回答。 @Adrian 建议使用 rake 任务,@lucapette 提到了 seed.rb 方法。种子更多地用于初始数据库输入,并且对于 rake 任务,我仍在等待来自 Adrian 的更多信息。还有什么建议吗?
  • 这里有很多好的答案! @abdollar,你的答案最适合我的情况。

标签: ruby-on-rails database migration database-schema


【解决方案1】:

听起来您每年进行一次大型操作(使用 yml 文件加载数据),但每月进行一次较小的操作。

根据我对统计数据的经验,您最终可能会执行越来越多的此类操作来清理和添加更多数据。

我会使用像resqueresque scheduler 这样的作业处理框架。

您可以安排作业每月、每年、每天运行一次或持续运行。作业类似于加载 yml 文件(或 yml 文件集)或清理数据。您可以控制要发送到您的作业的参数,这样您就可以使用一个类,但可以根据您对作业进行排队或安排作业的方式来交替更新或清理您的数据的方式。

【讨论】:

  • 谢谢!我真的很喜欢resque的想法。我去看看。
【解决方案2】:

首先,我不得不说这是一个非常有趣的问题。据我所知,从迁移中加载数据并不是一个好主意。一般来说,您应该使用 db/seeds.rb 在您的数据库中加载数据,我认为编写一个小类帮助程序放入您的 lib 目录然后从 db/seeds.rb 调用它可能是个好主意。我想您可以按以下方式组织文件:

lib/data_loader.rb
lib/years/2009.rb
lib/years/2010.rb

显然,您应该清除迁移并以您喜欢的方式为 lib/data_loader.rb 编写代码,但我只是想提供一个大致的想法,即如果我必须面对问题,我将如何组织我的代码像这样。

我不确定我是否以有帮助的方式回答了您的问题,但我希望确实如此。

【讨论】:

  • 感谢您的帖子!我知道种子主要用于向数据库输入初始数据。我完全不明白 seed.rb 如何用于每年更新数据。使用这种方法,一旦我需要更新数据库内容,我应该如何调用 rake db:seed?
  • 不客气,你可以编写你的“data_loader”,让它可以处理“年的事情”。我在想像“data_loader.load_current_year”之类的东西,但阅读其他回复我认为你也应该这样做。使用任务甚至可能是更好的解决方案,您应该编写一个将年份作为参数加载的任务。
  • 谢谢! According to DHH 种子应该在你第一次设置数据库时使用。如果我想有可能从头开始,问题真的是要让seeds.rb 保持最新。初始数据类型一直在变化:)
【解决方案3】:

如果我是你,我会创建自定义 rake 任务。您将可以访问所有模型和 activerecord 连接,并且每年一次您最终会这样做:

rake calculate

【讨论】:

  • 感谢您的回答!几个问题。关于数据,您将如何使用 rake 任务加载新数据?使用 yml 文件?我忘了说除了每年的 BIG 操作之外,我确实对数据进行了较小的调整(主要是更正),可能每月一次。有了 rake 任务,我最终会拥有数十个 rake 任务。我还需要跟踪执行顺序。
【解决方案4】:

我有一种情况,我需要从不经常更改的 CSV 文件加载数据,并每天从 Internet 更新数据。我将包含一个关于如何执行前者的完整示例。


首先我在lib/tasks/update.rake 中有一个 rake 文件:

require 'update/from_csv_files.rb'

namespace :update do

  task :csvfiles => :environment do
    Dir.glob('db/static_data/*.csv') do |file|
      Update::FromCsvFiles.load(file)
    end
  end

end

=> :environment 表示我们可以通过常用模型访问数据库。

然后我在lib/update/from_csv_files.rb 文件中有代码来做实际的工作:

require 'csv'

module Update
  module FromCsvFiles

    def FromCsvFiles.load(file)
      csv = CSV.open(file, 'r')
      csv.each do |row|
        id = row[0]

        s = Statistic.find_by_id(id)
        if (s.nil?)
          s = Statistic.new
          s.id= id
        end

        s.survey_area = row[1]
        s.nr_of_space_men = row[2]
        s.save
      end
    end

  end
end

然后,只要我的 CSV 文件更改以加载新数据,我就可以运行 rake update:csvfiles。我还有另一项以类似方式设置的任务来更新我的日常数据。


在您的情况下,您应该能够编写一些代码来加载您的 YML 文件或直接进行计算。要处理较小的更正,您可以创建一个通用方法来加载 YML 文件并使用 rake 任务中的特定文件调用它。这样,您只需要包含 YML 文件并使用新任务更新 rake 文件。要处理执行顺序,您可以创建一个 rake 任务,以适当的顺序调用其他 rake 任务。我现在只是抛出一些想法,你比我更清楚。

【讨论】:

  • 感谢@Gieron 的回答。这看起来很方便处理 CSV 输入。不错!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-25
  • 1970-01-01
  • 1970-01-01
  • 2015-08-01
  • 1970-01-01
  • 2012-08-27
相关资源
最近更新 更多