How to view the SQL of migrations in Laravel with `php artisan migrate --pretend`

Video thumbnail

When you want to execute migrations, we have a very useful option: the --pretend command. This command allows us to obtain the SQL that Laravel would execute internally in the database. In other words, it doesn't apply the changes directly, but rather shows you the SQL statements that are going to be executed.

If you work with Laravel long enough, sooner or later you find yourself in this situation: you need to know the exact SQL a migration will run, but you cannot afford to run it directly. Whether it's because you're in production, in a shared staging environment, or simply because you want to review the changes thoroughly before touching the database.

That exactly happened to me. I had several migrations out of sync with the database and running a blind migrate was not an option. That’s where I discovered one of the most useful (and least exploited) Artisan options.

Why you need to see the SQL of a Laravel migration

Laravel abstracts the database very well, but that convenience comes at a price: many times you don't see the actual SQL being executed underneath.

Seeing that SQL is key when:

  • You are working in shared environments.
  • You don't have access to the server terminal.
  • You need to validate delicate changes (alter tables, indexes, constraints).
  • You want to execute the SQL manually from a manager like phpMyAdmin or DBeaver.

In my case, the problem was twofold: many accumulated migrations and zero margin for error. I needed to know exactly what was going to happen before it happened.

The php artisan migrate --pretend command explained with a real example

For example, as you can see on the screen, many migrations appear. This is because I have a bad synchronization between the migrations and the database, but well… that's another story.

$ php artisan migrate --pretend

As you can see, Laravel spits out all the SQL into the console. The only details are that:

  1. Some lines have strange characters (weird icons).
  2. It doesn't add semicolons at the end of each statement.

Exactly what --pretend does

  • Iterates through all pending migrations.
  • Translates the Schema Builder into actual SQL.
  • Prints CREATE, ALTER, DROP statements, etc., to the console.
  • Does not apply any changes to the database.

So, you have to give it a bit of formatting to make it more legible. If you want, you can ask ChatGPT to format it for you. But beyond that, the most important thing is that you already have the SQL ready to execute in your database.

What it DOES NOT do (and common mistakes)

It's worth making this clear:

  • ❌ It does not execute migrations.
  • ❌ It does not update the migrations table.
  • ❌ It does not guarantee that the SQL is "production-ready" exactly as it comes out.

And here enters the part that almost nobody mentions.

What is this for?

You might be wondering: what can this be useful for?

As I have mentioned in other videos, this is especially valuable when you are working in shared environments, such as staging or production servers.

In these environments:

  1. You don't always have access to the terminal.
  2. Therefore, you cannot run php artisan migrate directly.
  3. But you can access the database manager (for example, phpMyAdmin or DBeaver).

So, if you need to create new tables or apply changes, you can copy this SQL and execute it directly.

Before I knew about this option, what I used to do was:

  1. Go to the database status manager.
  2. Export the newly created table.
  3. Take the resulting SQL.
  4. Then execute it in production.

A more cumbersome process, especially if you had to modify existing tables.

With --pretend, everything is easier

Now, with this --pretend option, everything is simplified:

  1. You can directly see the SQL, even if the migration modifies existing columns or adds constraints.
  2. You no longer depend on exporting from the visual manager.
  3. And you can easily copy/paste the SQL to execute it in other environments.

Real problems when using --pretend (and how to fix them)

The command works, but it isn't perfect.

SQL without semicolons

One of the first details I noticed is that many statements come out without a ; at the end. If you copy and paste that directly into a database manager, it might give you errors.

Solution:

A quick formatting (even asking Gemini to clean it up) and you're done.

Strange characters in the console

Depending on the system and the version, some lines appear with weird symbols or control characters. It's not serious, but it is annoying if you want to reuse the SQL.

In my case, it was enough to:

  • Copy the output
  • Clean it in an editor
  • Adjust the format

The important thing is that the SQL content is there.

How to format SQL quickly

Quick options:

  • Code editor + search/replace
  • Online SQL formatter tools
  • Or directly… ask ChatGPT

Beyond the format, the real value is that you already have the exact SQL that Laravel would execute.

Using migration SQL in environments without terminal access

This is where --pretend really shines.

In many staging or production environments:

  • You cannot use php artisan.
  • But you do have access to the database.

That means you can:

  • Run migrate --pretend locally.
  • Copy the SQL.
  • Run it manually in:
  • phpMyAdmin
  • DBeaver
  • MySQL Workbench
  • The manager you use

I used to do something much more cumbersome: I would create the table locally, export it from the manager, and then execute 그 SQL in production. It worked… but it was slow and fragile, especially when modifying existing tables.

With --pretend, that pain disappears.

How I did it before and why --pretend is better

Before:

  • Create or modify tables locally.
  • Export structure.
  • Adjust the SQL manually.
  • Execute in production.
  • Pray not to forget anything.

Now:

  • A single command.
  • SQL generated directly by Laravel.
  • Includes alters, indexes, and constraints.
  • Much less margin for error.

In real scenarios, the difference is huge.

Alternatives to inspect migrations in Laravel

Although --pretend is my favorite option, it's not the only one.

Reviewing migration files

  • Going into database/migrations and reading the up() and down() methods helps to understand the logic, although it's not always trivial to mentally translate that to SQL, especially in large migrations.
  • DB::statement and raw SQL

For more advanced cases (views, functions, triggers), many times you end up using pure SQL:

DB::statement("CREATE VIEW my_view AS SELECT ...");

There's no mystery here: the SQL is explicit. But for that very reason, --pretend remains key when you use the Schema Builder.

Frequently Asked Questions about Laravel Migration SQL

  • Does --pretend execute anything in the database?
    • No. It only shows the SQL.
  • Can I use that SQL directly in production?
    • Yes, but review and format it first.
  • Does it work for modifying existing tables?
    • Yes, and in fact, it's one of its biggest benefits.
  • Why doesn't Laravel include semicolons?
    • Because the output is intended for reading, not as a final script.

Conclusion

If you ever need to see, review, or reuse the SQL of your Laravel migrations, php artisan migrate --pretend is an essential tool. Not only does it save you time, but it gives you real control in scenarios where running migrations directly is not an option.

Since I started using it, I left behind many unnecessary manual processes. It's not perfect, but used correctly, it's one of those little gems that let you work with much more peace of mind.

Discover how to view the SQL that migrations execute in Laravel without running them. Perfect for environments without terminal access.

I agree to receive announcements of interest about this Blog.

Andrés Cruz

ES En español