2

Hello everyone

I'm going to try to explain my problem as clear as possible, feel free to ask me more precision if you didn't understand what I meant and forgive my mistakes, English is not my mother tongue.


My goal

I want to start using migrations again because I need to create a new table, after a year where developers of my company bypassed them by creating/deleting/updating tables directly from phpmyadmin.


The things you have to know

The last migration was a year ago, but many tables have been created without migrations since that time.


Why I need your help

I'd like to know what is the best way to start using again migration without losing data or tables, because I'm working on an environment production. What is the best way to do that ? Keeping the migrations that already exists and just ignoring the tables that have been created ? Deleting all migration files and deleting all the row in the migration table ?

If I delete all the migration files and truncate the migration table, will a php artisan migratewill have any impact on the existing schema ?

What is the best practice ? Should I recreate all the migrations of all the tables of my schema ? Or should I create only one migration with the new table I want to create ?

Community
  • 1
  • 1
McKenneii
  • 276
  • 2
  • 18

3 Answers3

1

You could start from scratch by deleting all migrations and truncating the migrations table.

Then take a look at this post to recreate all the migrations for your current database schema.

Bram Verstraten
  • 1,414
  • 11
  • 24
  • If I understand correctly, I'll have to add manually all those new generated migrations to the migration database so laravel don't run them ? – McKenneii Jul 04 '19 at 08:42
  • 1
    That is correct. Since your database is already up to date, you don't need to actually run the migrations. To test if it works you can set up your project locally and run the migrations. You should end up with the same database (without the actual data). – Bram Verstraten Jul 04 '19 at 08:50
1

Laravel keeps track of the migrations using a dedicated table that records when they were applied. When any one migration gets run, it inserts a new record in the table, and if you roll back a migration the corresponding record is deleted. You can therefore prevent undesired migrations from being run by adding them to this table.

My advice would be as follows:

  • Create the missing migrations
  • Run them on your local copy to get the database in the required state there
  • Export the migrations table
  • Import it to the production database
  • If you have any additional migrations you want to run after the ones you ran locally, run them in production

I'd definitely be careful to have a dry run beforehand though - perhaps after exporting the migrations, import the production database to your local copy, then import the migrations, and check it there.

I'd also be inclined to take steps to stop people applying changes to the production database directly - it's a very dangerous step that avoids accountability and makes it hard to test your application locally. Perhaps lock down PHPMyAdmin.

Matthew Daly
  • 9,212
  • 2
  • 42
  • 83
  • Creating the missing migrations is hard / not possible. They might have added columns to tables I'm not aware of. You're saying the I should run the migrations locally then export the result in production, is it a bad practice to run migrations in production ? – McKenneii Jul 04 '19 at 08:53
  • 1
    @McKenneii No, it's not a bad practice per se, but if those tables already exist running them will fail, and it might have negative consequences. The purpose of a migration is to apply changes to a database's structure, and if that change has already been applied then you don't want to run that migration. This approach is about faking the migrations. – Matthew Daly Jul 04 '19 at 08:58
  • @McKenneii What do you mean that they might have added columns to tables you're not aware of? You should be able to export the production database and reverse engineer it from there – Matthew Daly Jul 04 '19 at 08:59
  • Then the solution of Bram Verstraten might work : deleting my migration files, truncating the migration table, using a generator to create all the migrations according to my current database schema then adding manually those files to the migration table. Like that laravel won't try to run the migrations. Yes, I could try to reverse engineer, but the schema is kinda huge, and it would take ages to look table to table and migration to migration, to see the changes that have been made via PHP my admin directly. – McKenneii Jul 04 '19 at 09:04
  • @McKenneii If one of those third-party tools will generate satisfactory migrations for you, then that's probably the easiest way to go. I'd definitely take steps to stop developers making manual changes to the production database though, otherwise you risk winding up in the same situation again – Matthew Daly Jul 04 '19 at 09:08
  • I'll find a way to stop developers making changes like that. I'll teach them how to use properly migrations once the database and migrations are correct again. Thanks for your help it's much appreciated. – McKenneii Jul 04 '19 at 09:15
0

Mostly in these cases I try to sync migrations with my table so that I don't lose the current data which is on the database and I know that my migrations are updated . So I from the first table whatever you have added in your table manually, you have to add that to your migration too . In this case in future if you need to create a database truncate or anything else you know that your migrations are already up to date . To be honest the best practice is to make the changes in your migration not in the database so you have not done the best practice so . this is the best practice that even can be done in your case so you make a migration to your project like this :

php artisan make:migration added_photo_to_user_table --table=users

and then in your migration :

 public function up()
{
    Schema::create('users', function (Blueprint $table) {
        $table->text('photo')->nullable;

    });
}

then u have to run the command

php artisan migrate

but in your case because you added the fields to the database you don't need to run the last command you just have to make migrations so in future if you want to make update to the database you do it as the best practice and you don't encounter any data lost .

McKenneii
  • 276
  • 2
  • 18
Farshad
  • 1,830
  • 6
  • 38
  • 70