Страницы

Поиск по вопросам

понедельник, 17 июня 2019 г.

Когда может быть полезна команда rake db:schema:load?

В Rails есть команда rake db:schema:load. Когда она может быть полезна, в каких случаях ее применять?


Ответ

Команда полезна, если вам нужно одним махом выставить структуру в базе данных такую же, как в schema.rb или schema.sql вашего проекта.
Обычно структура БД модифицируется через миграции и rake db:migrate. Такой способ хорош по трем причинам:
Инкрементальное изменение БД - накатываются только те миграции, которые еще не накатывались на текущую БД; Нет угрозы потери существующих данных - в уже существующие таблицы и данные в них не вносятся изменения, если только это явно не указано в новых миграциях; Возможность отката на n миграций назад - с помощью rake db:rollback
При этом также обновляется файл schema.rb. После последовательной накатки всех миграций, в этом файле будет структура, отражающая все изменения через миграции, от самой первой до самой последней из накатанных. И, по-хорошему, этот файл нужно коммитить в git наряду с другими файлами проекта.

Теперь представим ситуацию:
В проекте заведены несколько веток, на несколько разных фич; В каждой ветке, так или иначе, оказалось нужно модифицировать структуру БД; Значит в каждой ветке есть какие-то свои миграции; Мы находимся в ветке A, создали в ней миграции, накатили их - изменили структуру БД; Внезапно нам понадобилось перейти на ветку Б и что-то сделать там; Мы перескакиваем на нее с помощью git checkout Б Теперь в редакторе мы видим код ветки Б, и можем с ним работать; Но в БД осталась структура данных, созданная за счет миграций из ветки А.
Вот такой конфликт. В идеале нам нужно убрать из БД все таблицы, поля и индексы, созданные миграциями из ветки А, перейти на ветку Б, и накатить все миграции из ветки Б. Примерно так:
rake db:rollback - n-раз, чтобы откатить n-миграций; git checkout Б rake db:migrate
А когда мы все сделаем в ветке Б и захотим вернуться в ветку А - нам понадобиться снова проделать эту последовательность операций. Откатить все миграции ветки Б, перейти на ветку А, и накатить все миграции ветки А.
rake db:schema:load помогает избавиться от этого. Дело в том, что в каждой ветке, когда мы создавали миграции, накатывали их и делали коммит - мы коммитили также и файл schema.rb. Значит, если мы с ветки А перейдем в ветку Б - мы увидим, что структура в schema.rb соответствует ровно тем миграциям, которые должны применяться в ветке Б. И мы можем эту структуру просто загрузить в БД. В итоге - алгоритм перехода с ветки на ветку упрощается до:
git checkout Любая-ветка rake db:schema:load
Но остается нюанс. Так как db:schema:load, по сути, накатывает готовую структуру на базу данных с нуля - все существующие таблицы, и, что важно нам, данные в таблицах - удаляются. То есть на выходе мы получаем, пусть и БД с актуальной структурой, но без данных. И накатывание этих данные нам нужно продумывать отдельно. Один из вариантов - хранить накатку данных в seeds.rb и после перехода на другую ветку и применения rake db:schema:load применять также rake db:seed

Комментариев нет:

Отправить комментарий