Страницы

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

воскресенье, 8 марта 2020 г.

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

#ruby_on_rails


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


Ответы

Ответ 1



Команда полезна, если вам нужно одним махом выставить структуру в базе данных такую же, как в 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.

Ответ 2



Она может быть полезна в том случае, если вам требуется воссоздать структуру базы данных в другом окружении/базе, не задействуя миграции (допустим по той причине, что они выполняются слишком долго). Например, для тестового окружения вы можете выполнить команду rake db:test:load и в тестовой базе данных будет развернута текущая схема из db/schema.rb, без последовательного выполнения миграций. Это становится особенно важно в том случае, когда вы работаете в контейнерах и прогоны тестов у вас начинаются каждый раз с чистой базы данных, а схлапывать старые миграции (заменяя их содержимым schema.rb) вы в силу каких-то причин не хотите (например, у вас там хранятся комментарии по причинам выбора индекса).

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

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