FormatterHQ

SQL to Laravel Migration

Paste MySQL, MariaDB, PostgreSQL or SQLite CREATE TABLE statements and get Laravel Schema::create migrations with foreign keys, indexes and defaults.

Input SQL
Output PHP
Ready.

How to use the SQL to Laravel Migration

  1. Paste one or more CREATE TABLE statements, for example from SHOW CREATE TABLE or a schema dump.
  2. Select the SQL dialect: MySQL, MariaDB, PostgreSQL or SQLite.
  3. The migrations are generated automatically; click Convert after edits.
  4. Save each migration under database/migrations with a timestamped name and run php artisan migrate.

Convert SQL to Laravel migrations

This SQL to Laravel migration converter reads CREATE TABLE statements and writes the equivalent Laravel migration using the schema builder. It is the fastest way to bring a legacy database, a schema designed in a GUI tool, or a mysqldump --no-data file under Laravel's migration system, so the schema can be versioned and recreated with php artisan migrate.

Example

Input:

CREATE TABLE posts (id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,user_id BIGINT UNSIGNED NOT NULL,slug VARCHAR(191) UNIQUE,body TEXT NULL,price DECIMAL(8,2) DEFAULT 0.00,is_published TINYINT(1) NOT NULL DEFAULT 0,status ENUM('draft','live') DEFAULT 'draft',created_at TIMESTAMP NULL,updated_at TIMESTAMP NULL,FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,INDEX idx_slug (slug));

Output inside the generated up() method:

Schema::create('posts', function (Blueprint $table) {$table->id();$table->foreignId('user_id')->constrained()->cascadeOnDelete();$table->string('slug', 191)->unique();$table->text('body')->nullable();$table->decimal('price', 8, 2)->default(0.00);$table->boolean('is_published')->default(false);$table->enum('status', ['draft', 'live'])->default('draft');$table->timestamps();$table->index('slug', 'idx_slug');});

Each table becomes its own anonymous migration class with a matching down() method that calls Schema::dropIfExists. The header comment suggests the file name, such as create_posts_table.php.

What gets converted

  • Primary keys: an auto-increment id becomes $table->id(); an INT or SERIAL id becomes increments('id'). Composite primary keys become $table->primary([...]).
  • Foreign keys: integer columns with a FOREIGN KEY become foreignId()->constrained(). The short form is used when the name follows Laravel's convention (user_id to users.id); otherwise the table and column are passed explicitly. ON DELETE/ON UPDATE CASCADE, SET NULL and RESTRICT map to cascadeOnDelete(), nullOnDelete(), restrictOnDelete() and their update versions.
  • Types: VARCHAR(n) to string (length kept unless it is 255), TEXT variants, DECIMAL(p,s), FLOAT, DOUBLE, DATE, DATETIME, TIMESTAMP, TIMESTAMPTZ, JSON, JSONB, UUID, ENUM, BLOB and INET. TINYINT(1) becomes boolean, and UNSIGNED integers use the unsigned... methods.
  • Modifiers: NULL adds nullable(), UNIQUE adds unique(), DEFAULT adds default(), DEFAULT CURRENT_TIMESTAMP or NOW() adds useCurrent(), and column comments are kept.
  • Laravel conventions: created_at plus updated_at collapse into timestamps(), and deleted_at becomes softDeletes().
  • Indexes: INDEX, UNIQUE and FULLTEXT keys become index(), unique() and fullText(), with the original index name preserved.

Limitations

Only CREATE TABLE is converted. ALTER TABLE, views, triggers and stored procedures are skipped, and a paste with no CREATE TABLE at all produces an error. Unknown types fall back to string, so check columns like GEOMETRY or MONEY by hand. Table options such as ENGINE, CHARSET and COLLATE are not carried over, because Laravel takes them from config/database.php.

Nullability follows what the SQL states explicitly. A column that is nullable only by default, with neither NULL nor NOT NULL, is generated without nullable(), so add it where you need it. Also order your files so referenced tables are created first; migrations run in file-name order, and a foreign key to a missing table fails.

Privacy

Your schema is parsed and converted in the browser, so table and column names are never uploaded. Check the SQL first with the SQL validator, tidy it with the SQL formatter, or build a model and migration from sample data with JSON to Laravel model.

Frequently asked questions

Can I convert a whole database dump at once?
Yes. Paste every CREATE TABLE statement together; each one becomes a separate migration. Other statements in the dump, such as INSERT or SET, are ignored as long as the SQL parses.
Does it generate Eloquent models too?
No, it only writes migrations. Create the models with php artisan make:model Post, or use the JSON to Laravel model tool if you have a sample record, which generates both.
Why did my foreign key use constrained('table', 'column')?
The short constrained() form only works when the column name matches the table, like user_id referencing users.id. For other names, such as author_id referencing users, the converter passes the table and column explicitly.
Is SQL Server supported?
The dialect list covers MySQL, MariaDB, PostgreSQL and SQLite, the databases Laravel projects most often migrate from. For SQL Server DDL, try the MySQL setting after removing bracket quoting and T-SQL specific options.
Can I use this with Laravel's schema:dump?
They solve different problems. php artisan schema:dump stores the current schema as one SQL file, while this tool produces readable, editable migration classes, one per table.

Last updated September 26, 2026

Guides

Related tools