Цель: Используя задачу КРОНА (или другое запланированное событие) для обновления базы данных с ночным экспортом данных из существующей системы.
Все данные создаются/обновляются/удаляются в существующей системе. Веб-сайт делает не непосредственно интегрируются с этой системой, таким образом, приложение для направляющих просто должно отразить обновления, которые появляются в экспорте данных.
У меня есть a .txt
файл ~5 000 продуктов, который похож на это:
"1234":"product name":"attr 1":"attr 2":"ABC Manufacturing":"2222"
"A134":"another product":"attr 1":"attr 2":"Foobar World":"2447"
...
Все значения являются строками, включенными в двойные кавычки ("
) это разделяется двоеточиями (:
)
Поля:
id
: уникальный идентификатор; алфавитно-цифровойname
: название продукта; любой символvendor_name
: строка; любой символvendor_id
: уникальный идентификатор поставщика; числовойИнформация о поставщике не нормализована в существующей системе.
Что такое лучшие практики здесь? Это должно хорошо удалить продукты и таблицы поставщиков и переписать с новыми данными по каждому циклу? Или лучше только добавить новые строки и обновить существующие?
Примечания:
Orders
это сохранится через ночной импорт базы данных. OrderItems
должен будет быть подключен к идентификаторам продукта, которые указаны в файле данных, таким образом, мы не можем полагаться на первичный ключ автопостепенного увеличения, чтобы быть тем же для каждого импорта; уникальный алфавитно-цифровой идентификатор должен будет использоваться для присоединения products
кому: order_items
.rake
задача для использования Product.create(...)
и Vendor.create(...)
синтаксис стиля.Я бы не стал удалять таблицы продуктов и поставщиков в каждом цикле. Это приложение для рельсов? В таком случае есть несколько действительно хороших помощников 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 будет искать продукт в базе данных по указанному вами идентификатору, и, если не может найти его, создаст новый.Что действительно удобно в этом способе, это то, что ActiveRecord будет сохранять в базу данных только в том случае, если какие-либо данные изменились, и он будет автоматически обновлять любые поля меток времени, которые у вас есть в таблице (updated_at), соответственно. Еще одна вещь, поскольку вы будете искать записи по идентификатору (id из файла), я обязательно добавлю индекс для этого поля в базе данных.
Чтобы выполнить задачу rake, я бы добавил файл rake в каталог lib / tasks вашего приложения rails. Мы назовем это 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» из командной строки.
file.each do | line | products_array = line.split (":") end
Используйте find_or_initialize для заполнения вашей базы данных, например:
Product.find_or_initialize_by_name_and_vendor_id ("foo", 111)
Поскольку продукты на самом деле меняются не так часто, лучший способ, который я могу найти, - это обновлять только те записи, которые меняются.
Если у вас есть код нормализации в моделях, вы можете использовать Product.create и Vendor.create, иначе это будет просто излишним. Кроме того, обратите внимание на вставку нескольких записей в одну транзакцию SQL, это намного быстрее.