目标:使用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
。 rake
任务才能使用Product.create(...)
和Vendor.create(...)
样式语法。 最佳答案
我不会在每个周期都删除产品和供应商表。这是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”。