Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

eludic's avatar

Migrate and Seed only once

I have an application which needs to be updated. The application database table "institute" already has a column "report" which is an int value. This needs to be changed and I would be adding a new column called "reports" which will populate according to client submission.

I have already written the migration for the same and added the following code to the DatabaseSeeder.php file:

$institutes = DB::table('institutes')->get();
        foreach($institutes AS $institute){

            if(!empty($institute->report)){
                $reports[] = $institute->report;
                $jsonreports = json_encode($reports);

                // Store this and reset file_auditreport
                DB::table('institutes')->where('id', $institute->id)->update([
                    'report'      =>  0,
                    'reports'     =>  $jsonreports
                ]);
            }
        }

My question is, how can I make sure Laravel runs this only once and not everytime I run the command php artisan db:seed as I do not want Laravel to run this in the future if in case there is an update to be made.

Hope this makes sense.

0 likes
6 replies
goatshark's avatar

@eludic For the seeders, I've done all sorts of things to check for the existence of records and only add them if they are not already present. When I do that, I typically use the run() method to call protected functions, like this:

    public function run()
    {
        $this->makeRoles();
    }

Then I will have something like:

    protected function makeRoles()
    {
        if ( ! $this->adminExists() ) {
            Role::create(['name'=>'Admin','slug'=>'admin']);
        }
    }

    protected function adminExists()
    {
        return Role::whereName('Admin')->exists();
    }

That's just an example. I think the most important thing to realize is that those seeders are just classes.

eludic's avatar

Makes alot of sense. Was thinking the same while version application version. However this one does not have this feature. In that case how do I prevent it from running again?

goatshark's avatar

You can base your seeder decisions on environment variables and snag the version from env().

I don't understand your question. Are you trying to have the seeder not run at all under certain circumstances?

If you're talking about your migration, php artisan migrate and it's commands should handle all of that for you. You can re-run php artisan migrate and not stomp on previous migrations.

eludic's avatar

Yeah I want this code to only run once and not the next time when db:seed command is executed

goatshark's avatar

If you put the logic for deciding whether or not to create the records in your seeder, then that seeder becomes idempotent and it won't matter if it is executed multiple times.

However, if you don't want that logic in the individual seeder classes, and if you are firing your seeders from Databaseseeder::class, you could add the logic there to decide whether or not to run each seeder.

Please or to participate in this conversation.