2013-09-02 3 views
18

Я работаю над приложением, которое уже развернуто в некоторых тестовых и промежуточных системах и на разных рабочих станциях разработчиков. Мне нужно добавить дополнительные справочные данные, но я не уверен, как их добавить.Как добавить новые данные семян в существующую базу данных рельсов

В большинстве советов используется использование seed.rb, однако я понимаю, что это выполняется только один раз, когда приложение изначально развертывается. Поскольку мы не хотим перестраивать тестовые и промежуточные базы данных так, чтобы мы могли добавить 1 строку справочных данных, есть ли другой способ добавить данные?

Я думаю об использовании миграции db, это правильный подход?

Благодаря

+2

Вы можете запустить 'seed.rb' столько раз, сколько хотите, это обычный файл сценария ruby ​​... Хотя имейте в виду, что если вы запустили его раньше и снова запустите его, вы получите дубликаты. В вашем случае, если вы хотите просто добавить строку данных, то «рейк-задача» или использовать бегун скрипта http://guides.rubyonrails.org/command_line.html#rails-runner. Я не думаю, что миграция подходит для это все же. – j03w

ответ

26

Создайте файл seed.rb, чтобы разрешить текущее создание и обновление данных. Вы не ограничены только запуском семенного файла только один раз, и если вы считаете, что он используется только для первоначального развертывания, вы пропустите гибкость, которую он может предложить при настройке справочных данных.

Файл семена просто рубин, так что вы можете сделать что-то вроде:

user = User.find_or_initialize_by(email: '[email protected]') 
user.name = 'Bob' 
user.password = 'secret' 
user.role = 'manager' 
user.save! 

Это создаст новые данные, если он не существует или обновить данные, если он находит некоторые.

Если вы правильно структурируете файл семян, вы также можете создавать и обновлять зависимые объекты.

Я рекомендую использовать функцию bang save, чтобы исключить исключения в том случае, если объект не может быть сохранен. Это самый простой способ отладки семян.

Я использую seedbank gem, чтобы предоставить больше структуры для моих данных о семени, включая данные настройки для каждой среды, зависимые семена и многое другое.

Я не рекомендую использовать миграции для данных семян. Существует недостаток гибкости (как вы ориентируете данные семян только на одну среду, например), и нет реального способа создания повторно используемого набора данных, который может быть запущен в любое время для обновления конкретной среды. У вас также будет набор миграций, которые не имеют ссылки на вашу схему, и вам придется создавать новые миграции каждый раз, когда вы хотите генерировать новые или изменять текущие данные.

+0

@ nmott- После добавления выше, как содержимое, мне нужно сделать rake db: seed? Если я сделаю так, что существующие снова заселяются? – Sam

+2

@Jsd Да, 'rake db: seed' будет загружать файл семени, и если определенная модель уже существует, то она найдет запись и перезапишет ее данными в файле семени. Это означает, что вы можете изменять данные в своем приложении и использовать начальный файл, чтобы регулярно обновлять его до стандартного набора данных. – nmott

+0

Похоже, что в конечном итоге это все равно будет раздуваться. –

2

Вы можете использовать миграцию, но это не самый безопасный вариант у вас есть. Скажем, например, вы добавляете запись в таблицу с помощью миграции, а затем в будущем вы меняете схему этой таблицы. Когда вы где-нибудь установите приложение, вы не сможете запустить rake db:migrate.

Семена всегда рекомендуются, потому что rake db:seed может быть запущен на полностью мигрированной схеме.

Если это просто запись, перейдите к консоли рельсов.

1

Лучше всего использовать метод идемпотентную как это в seed.rb или другое задание вызывается seed.rb:

Contact.find_by_email("[email protected]") || Contact.create(email: "[email protected]", phone: "202-291-1970", created_by: "System") 
# This saves you an update to the DB if the record already exists. 

Или похож на @ nmott'S:

Contact.find_or_initialize_by_email("[email protected]").update_attributes(phone: "202-291-1970", created_by: "System") 
# this performs an update regardless, but it may be useful if you want to reset your data. 

или использовать вместо assign_attributesupdate_attributes, если вы хотите присвоить несколько атрибутов перед сохранением.

0

я сделал что-то подобное в seed.rb

users_list = [ 
    {id: 1, name: "Diego", age: "25"}, 
    {id: 2, name: "Elano", age: "27"} 
] 

while !users_list.empty? do 
    begin 
    User.create(users_list) 
    rescue 
    users_list = users_list.drop(1) #removing the first if the id already exist. 
    end 
end 

Если элемент в списке с уже не существует, он будет возвращать исключение, то удалить этот пункт и попробовать еще раз, пока данный идентификатором Массив users_list пуст.

Таким образом, вам не нужно искать каждый объект перед его включением, но вы не сможете обновить значения, уже вставленные, как в коде @nmott.

0

Вместо изменения seeds.db, который вы, вероятно, захотите использовать для посева новых баз данных, вы можете создать настраиваемую задачу Rake (RailsCast #66 Custom Rake Tasks).

Вы можете создать столько задач Rake, сколько захотите. Например, скажем, у вас есть два сервера, одна из которых работает в версии 1.0 вашего приложения, другая - с 1.1, и вы хотите обновить оба до 1.2. Затем вы можете создать lib/tasks/1-0-to-1-2.rake и lib/tasks`1-1-to-1-2.rake, так как вам может понадобиться другой код в зависимости от версии вашего приложения.

1

Я использую файл семян для добавления экземпляров в новые или существующие таблицы все время. Мое решение прост. Я просто комментирую все остальные данные семени в файле db/seeds.rb, так что только новые исходные данные являются живым кодом. Затем запустите bin/rake db:seed.

Смежные вопросы