Как правильно обрабатывать изменения данных базы данных с миграциями и семенами laravel

У меня есть файлы миграции, которые создают исходную схему для базы данных, и у меня есть исходные файлы, которые заполняют исходную схему случайными данными и наборами типов.

Мое понимание миграций и семян заключается в том, что всякий раз, когда присоединяется новый член команды, он может просто запускать их и быть в курсе всех изменений базы данных и требуемых данных для работы продукта, плюс вы можете применять изменения к stg и prod, запустив файлы миграции.

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

Проблема, с которой я столкнулся, заключается в том, что ремесленник работает с миграциями и семенами так, что сначала он запускает все миграции, а затем все семена, и, похоже, у меня нет способа указать порядок, в котором они следует запустить. Итак, если я запускаю migrate:refresh --seed, я получаю ошибки, потому что он применяет последние миграции, которые вставляют новые данные (которые могут или не могут, в зависимости от типов, вставленных в начальные значения) до семя вставило свои данные.

Одно из решений, которое мы попробовали, — это также обновить начальные значения и проверить перед применением изменений в миграциях, которые вставляют данные, но это стало очень проблематично поддерживать.

Каково ожидаемое использование миграций и семян для этого сценария?

Обновить Чтобы было понятнее: допустим, у меня есть миграция для создания пользователей: Пользователи:{id, name, type} И у меня есть исходная информация для создания пользователей .

Я запускаю оба, и у меня есть таблица пользователей с кучей пользователей.

Проходит время, и мы решаем, что нам нужна таблица для user_types. Создается миграция, которая создаст новую таблицу и заполнит данные новых типов пользователей и обновлений, чтобы сопоставить текущий user.type с user.type_id.

Разработчики выполняют миграцию, и у них есть обновленная база данных.

К команде присоединяется новый разработчик. Он управляет миграциями. А потом семена. Это нарушает.

Теперь, если мы обновим начальные значения, чтобы они соответствовали последним, мы столкнемся с дублированием данных для таблицы user_types. Чтобы избежать этого, нам понадобится какой-то защитный код при миграции, чтобы не запускать вещи, если нет данных, и обновлять, если они есть.

Вопрос в том, правильный ли это способ использования миграции? Как передать изменение данных всем разработчикам без повторного запуска семян?


person lebobbi    schedule 17.03.2016    source источник
comment
Может быть, я неправильно понимаю, но я не могу придумать сценарий, в котором структура базы данных может или должна зависеть от фактических данных. Являются ли они случайными проблемами внешнего ключа, когда вам нужно создать родительские данные перед созданием дочерних данных?   -  person user1669496    schedule 17.03.2016
comment
Я обновил описание со сценарием   -  person lebobbi    schedule 17.03.2016
comment
Предполагается, что сеялки повторяются. У каждого сеялки есть Model::truncate() в качестве отправной точки.   -  person user2094178    schedule 18.03.2016


Ответы (2)


Из вашего объяснения, кажется, я понял.

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

Я бы также внимательно изучил документы https://laravel.com/docs/5.2/seeding в частности раздел "Использование фабрик моделей".

public function run()
{
    factory(App\User::class, 50)->create()->each(function($u) {
        $u->posts()->save(factory(App\Post::class)->make());
    });
}

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

Таким образом, вы обработаете отношения родитель/потомок и сделаете их очень четкими в коде, и в будущем будет очень легко добавлять дополнительные элементы. Кроме того, поскольку вы, по сути, начинаете с нуля каждый раз, когда запускаются сеялки, вы можете быть уверены, что это сработает как для новых, так и для существующих разработчиков.

person user1669496    schedule 17.03.2016
comment
Я думаю, мне все равно нужно будет проверять, прежде чем вставлять или изменять данные в миграциях для уже заполненных пользователей, верно? - person lebobbi; 17.03.2016

Я думаю, что миграции не должны зависеть от каких-либо данных в семенах. И семена должны ожидать последнюю схему миграции. Таким образом, всякий раз, когда ваша схема изменяется, вы должны соответствующим образом обновлять начальные значения и выполнять migrate:fresh --seed. По крайней мере, это то, что я делаю.

Поскольку вы уже делаете это, мне интересно, что делает этот процесс для вас «трудным». Можете ли вы уточнить?

person neochief    schedule 17.03.2016
comment
Да, дело в том, что мы ожидаем, что миграции помогут нам избежать этого: необходимости обновлять каждый раз, когда вносятся новые изменения. Чтобы мы могли запускать миграции на stg или даже prod, добавлять новые типы, изменять существующие, таблицы и т. д. - person lebobbi; 17.03.2016
comment
Ну, вы полагаете, что никогда не будете раздавать в производственной базе данных. Раздача предназначена только для тестирования. Итак, если у вас есть что-то в семенах, которые должны быть созданы в рабочей среде после выпуска, держу пари, вам следует перенести их в миграцию. @user3158900 user3158900 добавил отличный ответ, в котором разъясняется часть об удалении перед заполнением. - person neochief; 17.03.2016