1

I'm about to start building an API for an existing app with the DB already in production. Functionality will slowly be ported to the API in the future and the app will become more "API-centric".

One of the main starting points is to adopt migrations and a build process. I have reservations on the best way to create migrations for an existing schema without breaking production when they are executed.

As we would like to move quickly with porting functionality over to the API, we ideally want to recreate our current schema as part of our build process and get some core unit tests in place - as opposed to just creating migrations for future changes.

This is where I become unsure as to the best place to start.

What is the best approach for a task like this?

  1. Could the current schema be imported as our first migration?
  2. Could this initial migration be wrapped in something like: if ( App::environment() !== 'production' ) to ensure it isn't executed in a production environment?
  3. Is it ok to exclude a migration for a particular environment or could this cause problems?

Is there maybe another approach or something stupidly simple I'm missing? :)

2 Answers 2

3

I created a tool not to long ago that will generate all the migrations for your current database schema. It also adds the newly created migrations to the migrations table, as the tables already exist. You can get it here: https://github.com/Xethron/migrations-generator

Secondly, I use the following line of code in my DatabaseSeeder, but you can add it to any function you wish to disable in production:

if (App::environment() === 'production') {
    exit('Don\'t be stupid, this is a production server!!!');
}

It shouldn't be a problem if you stop execution by throwing an error or as I do above. If you don't, Laravel will believe the changes happened successfully and remove them from the migrations table, and cause errors when running your migrations. The only exception is if you exclude both the up and down code (But I can't see why you would want to do that)

Hope this helps.

Sign up to request clarification or add additional context in comments.

Comments

1

I wouldn't suggest running migrations in production environment at all, but if you must then make a backup copy of the database first and also create a copy of the database locally and do the migration there then test to make sure it all works properly.

  1. You could create your first migration and manually add all the schema layout to it. But I would actually do this in a few migrations to have each table as its own migration.
  2. Since migrations are run from the CLI using artisan you can pass the environment and the database you want the migration to be run on:

    artisan migrate --database="connectionName" --env="local"

  3. There is no issue running migration on a particular environment besides what I stated above for production.

Remember to add all existing schema layouts from step 1 (the migration file name excluding the extension e.g. 2014_03_25_143340_AddCountriesTable) to the migrations table in the database, otherwise running the command in step 2 will throw errors about table already exist.

Hope this helps.

2 Comments

Is there any reason you wouldn't run migrations in production? The reason I was thinking of using a guard within the migration was to prevent it from running in production - incase someone accidentally "migrated down" and dropped all the tables.
I somewhat prefer to do this manually depending on the project as I am in control of the changes rather than them being automated. But that's just personal preference.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.