Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Recommended / Standard handling of Laravel Data Migrations

Laravel ships with database migrations for managing CRUD operations regarding the structure of a database, but what is the appropriate/recommended/standardized way to handle migration of actual data?

My question is, should the data migration take place directly inside the database migration file? Should it be a seeder? Should it be a job that is dispatched from within the database migration? Where should such logic go. Sometimes these data migrations can become incredibly complex depending on what the database migration does, and in the spirit of maximizing readability and keeping responsibilities separate, I feel like the logic belongs somewhere else.

This question, I suppose, is more attributable to OOP programming structure and practice as a whole, rather than laravel specific, but Laravel is the framework I'm working in right now so framing my question in that regard.

like image 822
mindfullsilence Avatar asked Feb 25 '21 19:02

mindfullsilence


People also ask

Is migration necessary in Laravel?

for testing/seeding, migration to another database or creating new local setup), then it is not necessary. Also models are not required but if you want to use Eloquent and other fancy Laravel things, then create them.

How does Laravel keep track of migrations?

How does Laravel do this? By keeping track of your migrations in a special database table. The php artisan migrate:install command will set things up for you so Laravel can manage these migrations. Over time, as your application grows, you will add more and more migrations.

What is the advantage of Laravel migrations?

The main benefit is that you will do it in your development server/station, and you may change the schema many times in development, migrate, rollback migrations, and re-migrate them, and as soon as your application id done, you don't have to remember what you have to do in your production environment, Laravel will do ...

What is the purpose database migration in Laravel?

Laravel Migration is an essential feature in Laravel that allows you to create a table in your database. It allows you to modify and share the application's database schema. You can modify the table by adding a new column or deleting an existing column.


2 Answers

I've done this several times, and I do it right there in the migration up() and down() functions unless we're talking about millions of records. I agree with you, it feels like there should be a clearly defined function in the migration for this. We want the data changed before another migration on the table is triggered, so I feel it needs to be done right away.

Using your example, this is what a simple migration would look like for splitting the name into a first_name and last_name in the up() function:

<?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');
        });
    }

...

If you have complex data changes, take a look at the $table->temporary(); option to create temporary tables to do data manipulation with SQL, and/or make command scripts which are called within the migration using the 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

like image 128
jon__o Avatar answered Sep 27 '22 21:09

jon__o


I prefer to separate data and structure migrations. I think that migration files should include only schema related queries.

Conditionally migration could contain data changes if:

  • Data is dependant on the time of deployment/migration (Can't really think of a case, but I am sure there are some :)).
  • We are making a schema change that directly affects the data. For example: changing the type of column or creating a new key that has to be seeded before future migrations take place.

Additional reasons why I prefer to have data in seeder files:

  • Running migrations on productions always carries certain risks. You can lower the risks of losing your data by testing the deployment process and using some fancy CD processes, but the risk is always present.

  • Static data that you think will never change, will change. For example, you start a new project in 2010 and the project's database contains table 'countries', which contains a list of countries and their properties. But after 2011 you get a new country: South Sudan. Will you create new migration or just update the seeder?

like image 30
Sigismund Avatar answered Sep 27 '22 20:09

Sigismund