Каков наилучший способ скопировать данные из одного поля в другое при создании миграции нового поля? - PullRequest
3 голосов
/ 09 апреля 2019

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

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

public function up()
{
    Schema::table('skills', function (Blueprint $table) {
        $table->tinyInteger('skill_type_id')->nullable()->comment = '1 for advisory skills, 2 for tools, 3 for language & framework';
    });
    $skill_object = (new \App\Model\Skill());
    $skills = $skill_object->get();
    if (_count($skills)) {
        foreach($skills as $skill) {
            $skill_type  = 1;
            if ($skill->is_tool) {
                $skill_type = 2;
            }
            $skill_object->whereId($skill->id)->update(['skill_type_id' => $skill_type]);
        }
    }
}

Ответы [ 4 ]

2 голосов
/ 10 апреля 2019

Вы можете сделать это (обновить данные) следующим образом в вашем сценарии.

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

Но вышеупомянутые решения мало рискованны, если вы пытаетесь сделать это с вашей производственной базой данных. Если кто-то по ошибке нажал URL-адрес и запустил сеялку несколько раз, это будет сложно.

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

1 голос
/ 10 апреля 2019

Вы можете самостоятельно разработать собственный способ решения этой задачи, но с точки зрения миграции они предназначены для управления и совместного использования схемы базы данных приложения * среди команды, а не фактических данных; )

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

ПРИМЕЧАНИЕ: Не включайте этот класс сеялки в DatabaseSeeder .

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

1 голос
/ 09 апреля 2019

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

public function up()
{
    Schema::table('skills', function (Blueprint $table) {
       DB::statement('UPDATE skills SET skill_type_id = IF(is_tool, 2, 1)');
    }
}
0 голосов
/ 12 апреля 2019

Учитывая ( laracast , переполнение стека ), я предпочитаю пройтись по предложениям, приведенным выше, так как я не должен поддерживать ни дополнительный маршрут, ни дополнительную миграцию (03 ).

Единственное улучшение, которое я могу предложить здесь, это то, что вы можете использовать транзакцию databse примерно так:

// create new column
DB::transaction(function () {
  update new column
  delete old column
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...