We help IT Professionals succeed at work.

Nothing to Migrate - My Journey into Larevel Purgatory

Bruce Gust
Bruce Gust asked
on
High Priority
35 Views
Last Modified: 2020-02-17
I'm trying to get things done quick.

I'm working on a Laravel project, I realize I need to alter the structure of a table so I just go into phpMyAdmin, do what needs to be done and then alter the corresponding migration file.

You're not supposed to do that, are you?

In the interest of keeping the migration file current, I just changed the schema. But then I began to wonder if that wasn't going to throw things off systemically and now, things are all cornfused.

First of all, just for the sake of my own edification: Migrations are not optional. Regardless of how incremental of a change you're making to your database, it all has to be done through the migration dynamic because that's a part of the way Larevel / Eloquent are processing things, correct?

Secondly, for the sake of cleaning up the mess i just described, here's what I did:

I created a "drop_video_table" migration and ran that successfully.
Here's the "create_videos_table" migration that I edited (perhaps incorrectly)

<?php

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

class CreateVideosTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('videos', function (Blueprint $table) {
            $table->bigIncrements('id');
			$table->string('title');
			[b]$table->binary('description');
			$table->binary('filename');[/b]
                         $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('videos');
    }
}

Open in new window


The part that I have in bold originally read:

$table-binary('code');

I changed that manually so it now is two additional fields.

Granted, I probably should've written an "alter_videos_table" migration, but lesson learned.

My dilemma is that when I go to run "$ php artisan migrate --path=database/migrations/2020_02_13_023156_create_videos_table.php," I get a message back that says, "Nothing to migrate."

OK, so I'm not going to try and pop the hood on phpMyAdmin again and alter my tables, but how do I get my new and improved videos table back on line?

Thanks!
Comment
Watch Question

CERTIFIED EXPERT
Most Valuable Expert 2018
Distinguished Expert 2019
Commented:
Hey Bruce,

A few pointers. It makes sense to always use the migrations in Laravel. It's not absolutely necessary, but it has some advantages. Firstly, it allows you to version control your Database (your Migrations get included in your git repo for example). Secondly, if you move your app to a different server, or a colleague wants to fire up your application, then you just need to migrate and the DB would be set up. As I say - it's not necessary - you can just create, edit, manage your DB through PHPMyAdmin and skip migrations altogether, but you'd lose the benefits I've just mentioned.

The reason you're getting the Nothing To Migrate error is likely because your migrations table on your DB already has an entry for the 2020_02_13_023156_create_videos_table migration. If you've ran this previously and then editied, Laravel won't run it again. You have a couple of choices here. You can delete the table (videos) and delete the entry from the migrations table. Then when you run the migration again, you should be good to go. A better way is to remove the edits from your migration and create a new migration that just adds the new columns.

Generally speaking, a migration runs once. To start with, this will have an up() method (ran with migrate) that creates the table along with it's columns. The down() method (ran with a rollback) will drop the table. If you later decide you want to alter the Database, then you create a new migration. The up() method adds / edits or deletes columns, and your down() method reverses thoses changes (deletes added / adds deleted / renames renamed!)

To edit a table, your new migration would look something like this

public function up() {
    Schema::table('videos', function (Blueprint $table) {
        $table->binary('description');
        $table->binary('filename');
    });
}

public function down() {
    Schema::table('videos', function (Blueprint $table) {
        $table->dropColumn(['description', 'filename'']);
    });
}

Open in new window

Bruce GustPHP Developer

Author

Commented:
Morning, Chris!

I kind of figured that was the case, as far as migrations serving as a "gameplan" for the app's database. To me it's reminiscent of OpenAPI and for that reason I can appreciate it's utility.

Let me ask you this, though: Is there something under the hood that REQUIRES migrations to be in place? In other words, if I were to skip the migrations dynamic altogether - not saying that's healthy or appropriate - would my queries still fire?

Another thing about the migrations dynamic that concerns me is that as I continue to move forward with my app's design and construction, it seems like I'm potentially clogging the pipes with multiple migration files that add a table, add a column, delete a table etc. It's like the system is looking at me and saying, "Would you make up your mind!" That as opposed to a situation where you have an intelligible collection of migrations that build your tables and that's it. In other words, you reserve your migrations for creating what represents your final draft of your database as opposed to multiple migrations that make incremental changes, delete tables that aren't even a part of the final app etc.

What's your view on that?

I'm going to delete the table that I just made using a migration and then create another migration that builds my new and improved table from scratch.

Thanks!
CERTIFIED EXPERT
Most Valuable Expert 2018
Distinguished Expert 2019

Commented:
Hey Bruce,

No - there's absolutely nothing that requires Migrations at all. The Migrations are simply helpers for creating and managing your DB. Once they've ran and your DB is up-to-date, Eloquent and your Models have no concept of a Migration - they just talk to the DB.

As for clogging up your pipes, don't worry about it. Migration files are small, and each migration is just a simple text entry in the DB, so there's no performance hit to using them. They don't effect run-time one bit. The benefits of having version-controlled text files that show the changelog to your DB as your app evolves far outways the 'hassle' of having lots of migrations files.

Technically, there's nothing stopping you from creating lots of migrations throughout the development stage, and once you're happy with the final schema, deleting all the migrations, dropping the DB and creating a 'clean' set of migrations, although I would suggest this isn't really necessary. This approach would only really work for the inital stage of development. After you've deployed your application, you're gonna want incremental migrations (unless you intend to completely drop your DB on each upgrade).

Some of this will depend in part on your own development cycle and whether or not you work with other developers. My approach is generally this: I create the migrations as I'm working through an app. If I need to make changes to the DB, then I create a new migration. All of this is version-controlled through git. When I find a change I want to make (or a bug I need to fix), I'll branch off git, make the changes to code, add a new migration and then commit/merge the changes back in.

In my git repo, I then have a changelog of exactly what code was changed and what db changes were made. I can clearly see that I changed a certain file and added a new DB column to fix a particular bug or add a new feature. If you're working with other developers, they can simply pull the repo, run migrate and they're immediately up to speed with the latest codebase and DB. Same goes for deploying to your production server - push your migration files and run migrate - your production DB is then up-to-date.
Bruce GustPHP Developer

Author

Commented:
OK! Sounds like the migration thing falls under the heading of best practices so I'm in!

Thanks!
CERTIFIED EXPERT
Most Valuable Expert 2018
Distinguished Expert 2019

Commented:
Haha - certainly falls under the 'easy-life' category for me :)