Рекомендуемая/стандартная обработка миграции данных Laravel

Laravel поставляется с миграциями базы данных для управления операциями CRUD в отношении структуры базы данных, но каков подходящий/рекомендуемый/стандартизированный способ обработки миграции фактических данных?

У меня вопрос: должна ли миграция data выполняться непосредственно в файле миграции database? Это должна быть сеялка? Должно ли это быть задание, которое отправляется из миграции базы данных? Куда деваться такой логике. Иногда эти миграции данных могут стать невероятно сложными в зависимости от того, что делает миграция базы данных, и в духе максимальной удобочитаемости и разделения обязанностей я чувствую, что логика принадлежит чему-то другому.

Этот вопрос, я полагаю, больше связан со структурой и практикой программирования ООП в целом, а не с конкретным laravel, но Laravel - это среда, в которой я сейчас работаю, поэтому формулирую свой вопрос в этом отношении.


person mindfullsilence    schedule 25.02.2021    source источник


Ответы (3)


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

Используя ваш пример, вот как будет выглядеть простая миграция для разделения name на first_name и last_name в функции up():

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
use Illuminate\Support\Facades\DB;

class Test extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::table('users', function (Blueprint $table) {
            $table->string('last_name')->after('name');
            $table->string('first_name')->after('name');
        });

        DB::statement("UPDATE users SET first_name = SUBSTRING_INDEX(name, ' ', 1), last_name = SUBSTRING(name from instr(name, ' ') + 1)");

        Schema::table('users', function (Blueprint $table) {
            $table->dropColumn('name');
        });
    }

...

Если у вас есть сложные изменения данных, обратите внимание на параметр $table->temporary();, чтобы создать временные таблицы для обработки данных с помощью SQL и/или создать командные сценарии, которые вызываются при переносе с использованием параметра Artisan::call().

$table->temporary(): https://laravel.com/docs/8.x/migrations#database-connection-table-options Artisan::call(): https://laravel.com/docs/8.x/artisan#programmatically-executing-commands

person jon__o    schedule 28.02.2021

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

Условно миграция может содержать изменения данных, если:

  • Данные зависят от времени развертывания/миграции (не могу придумать случай, но я уверен, что такие есть :)).
  • Мы вносим изменение в схему, которое напрямую влияет на данные. Например: изменение типа столбца или создание нового ключа, который необходимо заполнить перед будущими миграциями.

Дополнительные причины, по которым я предпочитаю иметь данные в файлах сеялки:

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

  • Статические данные, которые, по вашему мнению, никогда не изменятся, изменятся. Например, вы начинаете новый проект в 2010 году, и база данных проекта содержит таблицу «страны», которая содержит список стран и их свойства. Но после 2011 года вы получаете новую страну: Южный Судан. Вы создадите новую миграцию или просто обновите сидер?

person Sigismund    schedule 23.03.2021

Добавление к ответам @jon__o, и вы можете найти дополнительную информацию здесь. Кроме того, я рекомендую вам перейти по этой ссылке. где они использовали временные таблицы на основе hashed_id, где временные таблицы в основном идентичны обычным таблицам в базе данных. Он имеет множество функций, полезных для миграции.

Schema::create('temp_mappings', function (Blueprint $table) {
        $table->temporary(); // thanks, Laravel
        $table->integer('id')->primary();
        $table->string('hash_id');
    });
person I_Al-thamary    schedule 23.03.2021