Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Migrations Laravel Package

doctrine/migrations

Doctrine Migrations is a PHP library for managing database schema changes with versioned migrations. Generate, run, and roll back migrations safely across environments, track executed versions, and integrate with Doctrine DBAL/ORM for reliable deployment workflows.

Deep Wiki
Context7

Getting Started

Minimal Setup in Laravel

  1. Installation

    composer require doctrine/migrations
    
  2. Configure the Migrations Table Add this to your config/database.php under a new migrations section:

    'migrations' => [
        'table' => 'migrations',
        'column' => 'version',
        'column_hashed' => false,
        'order_column' => 'execution_order',
    ],
    
  3. Create the Migrations Table Run this Artisan command (adjust for your DB connection):

    php artisan doctrine:migrations:create --table=migrations
    
  4. First Migration Generate a new migration:

    php artisan doctrine:migrations:generate --name=CreateUsersTable
    

    Edit the generated file in database/migrations/ (e.g., 20240101000000_CreateUsersTable.php) with your schema changes.

  5. Execute the Migration

    php artisan doctrine:migrations:migrate
    

First Use Case: Schema Evolution

  • Use doctrine:migrations:generate to scaffold a migration for a new table/column.
  • Implement up() to add schema changes and down() to roll them back.
  • Test locally with php artisan doctrine:migrations:migrate --dry-run.

Implementation Patterns

Workflow Integration

  1. Artisan Command Wrapping Extend Laravel’s Artisan to trigger migrations in deployment workflows:

    // app/Console/Commands/Deploy.php
    use Doctrine\Migrations\Tools\Console\Command\MigrateCommand;
    
    protected $signature = 'deploy:database';
    public function handle() {
        $migrate = new MigrateCommand();
        $migrate->run(new ArrayInput(['migrate' => null]), new BufferedOutput());
    }
    
  2. Event-Driven Migrations Hook migrations into Laravel events (e.g., ModelCreating) via service providers:

    public function boot() {
        Model::creating(function ($model) {
            if ($model instanceof User && !Schema::hasTable('users')) {
                Artisan::call('doctrine:migrations:migrate');
            }
        });
    }
    
  3. Environment-Specific Config Use Laravel’s config caching to switch migration paths:

    // config/migrations.php
    'paths' => [
        'local' => database_path('migrations'),
        'production' => storage_path('app/migrations'),
    ],
    

    Override in .env:

    MIGRATIONS_PATH=production
    

Common Patterns

  • Transactional Migrations Wrap schema changes in a transaction for atomicity:

    public function up(SchemaManager $sm) {
        $sm->beginTransaction();
        try {
            $sm->createTable('users', [...]);
            $sm->commit();
        } catch (\Exception $e) {
            $sm->rollBack();
            throw $e;
        }
    }
    
  • Data Migrations Use doctrine/dbal for data manipulation:

    public function up(Connection $connection) {
        $connection->insert('users', ['name' => 'Admin', 'email' => 'admin@example.com']);
    }
    
  • Dependency Management Enforce migration order with dependsOn():

    public function getDependencies() {
        return ['20240101000000_CreateUsersTable'];
    }
    

Gotchas and Tips

Pitfalls

  1. Migration Table Locking

    • Issue: Long-running migrations can lock the migrations table, blocking other operations.
    • Fix: Use SET TRANSACTION ISOLATION LEVEL READ COMMITTED in down() or split migrations into smaller batches.
  2. Non-Deterministic Migrations

    • Issue: Migrations using NOW() or random data fail on replay.
    • Fix: Avoid dynamic values; use parameters or seed data separately.
  3. Doctrine DBAL vs. Laravel Schema

    • Issue: Mixing Schema builder and Doctrine\DBAL\Schema can cause conflicts.
    • Fix: Stick to one approach per migration or abstract the schema layer.

Debugging

  • Dry Runs Test migrations without applying:

    php artisan doctrine:migrations:migrate --dry-run
    
  • Rollback Debugging Use --down-to to target specific versions:

    php artisan doctrine:migrations:migrate --down-to=20240101000000
    
  • Logging Enable verbose output:

    php artisan doctrine:migrations:migrate -vvv
    

Extension Points

  1. Custom Migration Classes Extend Doctrine\Migrations\AbstractMigration for reusable logic:

    class BaseMigration extends AbstractMigration {
        protected function addIndex(SchemaManager $sm, string $table, string $column) {
            $sm->addIndex($table, [$column]);
        }
    }
    
  2. Pre/Post-Migration Hooks Use Laravel’s registerCommands to intercept migration events:

    public function registerCommands() {
        $this->commands([
            (new MigrateCommand())->setName('migrate:custom'),
        ]);
    }
    
  3. Migration Testing Mock the SchemaManager in PHPUnit:

    $sm = $this->createMock(SchemaManager::class);
    $sm->method('createTable')->willReturn(true);
    $migration = new CreateUsersTable();
    $migration->up($sm);
    

Configuration Quirks

  • Column Hashing Set column_hashed: true in config to store migration versions as hashes (useful for binary-safe environments).

  • Execution Order Use order_column to enforce migration sequence (e.g., for dependent tables).

  • Database-Specific SQL Use Doctrine\DBAL\Platforms to abstract platform differences:

    $platform = $connection->getDatabasePlatform();
    if ($platform->supportsForeignKeyConstraints()) {
        $sm->addForeignKeyConstraint(...);
    }
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
davejamesmiller/laravel-breadcrumbs
artisanry/parsedown
christhompsontldr/phpsdk
enqueue/dsn
bunny/bunny
enqueue/test
enqueue/null
enqueue/amqp-tools
milesj/emojibase
bower-asset/punycode
bower-asset/inputmask
bower-asset/jquery
bower-asset/yii2-pjax
laravel/nova
spatie/laravel-mailcoach
spatie/laravel-superseeder
laravel/liferaft
nst/json-test-suite
danielmiessler/sec-lists
jackalope/jackalope-transport