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.
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 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.
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 ...
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.
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
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:
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?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With