目标:使用CRON任务(或其他计划的事件)通过夜间从现有系统导出数据来更新数据库。

所有数据都是在现有系统中创建/更新/删除的。该网站没有与该系统直接集成,因此rails应用仅需要反射(reflect)数据导出中出现的更新。

我有一个约5,000种产品的.txt文件,如下所示:

"1234":"product name":"attr 1":"attr 2":"ABC Manufacturing":"2222"
"A134":"another product":"attr 1":"attr 2":"Foobar World":"2447"
...

所有值都是用双引号(")括起来的字符串,并用冒号(:)分隔。

字段是:
  • id:唯一ID;字母数字
  • name:产品名称;任何字符
  • 属性列:字符串;任何字符(例如大小,重量,颜色,尺寸)
  • vendor_name:字符串;任何字符
  • vendor_id:唯一的供应商ID;数值

  • 供应商信息未在当前系统中规范化。

    什么是最佳做法?可以在每个周期删除产品和供应商表并用新数据重写吗?还是仅添加新行并更新现有行会更好?

    注意:
  • 此数据将用于生成Orders,该代码将在每晚数据库导入过程中保持不变。 OrderItems将需要连接到数据文件中指定的产品ID,因此我们不能依靠自动递增的主键来确保每次导入都相同。需要使用唯一的字母数字ID将products连接到order_items
  • 理想情况下,我希望导入者对供应商数据进行标准化
  • 我不能使用普通的SQL语句,因此我想我需要编写一个rake任务才能使用Product.create(...)Vendor.create(...)样式语法。
  • 这将在EngineYard上实现
  • 最佳答案

    我不会在每个周期都删除产品和供应商表。这是Rails应用程序吗?如果是这样,那么有一些非常不错的ActiveRecord帮助器将为您派上用场。

    如果您有产品事件记录模型,则可以执行以下操作:

    p = Product.find_or_initialize_by_identifier(<id you get from file>)
    p.name = <name from file>
    p.size = <size from file>
    etc...
    p.save!
    

    find_or_initialize将通过您指定的ID在数据库中查找产品,如果找不到,则会创建一个新产品。这样做的真正方便之处在于,ActiveRecord仅在任何数据已更改的情况下才保存到数据库,并且它将相应地自动更新表中的所有时间戳字段(updated_at)。还有一件事,因为您将通过标识符(文件中的id)查找记录,所以我将确保在数据库中的该字段上添加索引。

    为了完成一个rake任务,我将一个rake文件添加到rails应用程序的lib/tasks目录中。我们将其称为data.rake。

    在data.rake内部,它看起来像这样:
    namespace :data do
      desc "import data from files to database"
      task :import => :environment do
        file = File.open(<file to import>)
        file.each do |line|
          attrs = line.split(":")
          p = Product.find_or_initialize_by_identifier(attrs[0])
          p.name = attrs[1]
          etc...
          p.save!
        end
      end
    end
    

    比调用rake任务,从命令行使用“rake data:import”。

    09-25 17:10
    查看更多