Framework: [5.5] migrate:fresh does not drop tables from all databases

Created on 7 Sep 2017  路  4Comments  路  Source: laravel/framework

  • Laravel Version: 5.5.x
  • PHP Version: 7.0.15
  • Database Driver & Version: MySQL 5.6.35

Description:

When running ./artisan migrate:fresh with multiple databases, command will only drop tables from the main database then produce a "Base table or view already exists" error due to tables in additional databases being defined within migrations.

Steps To Reproduce:

Define additional database, e.g. files
Add new table via migration, e.g. files
./artisan migrate:fresh

Most helpful comment

<?php

namespace Tests\Traits;

use Illuminate\Foundation\Testing\RefreshDatabaseState;
use Illuminate\Foundation\Testing\RefreshDatabase as FrameworkRefreshDatabase;

trait RefreshDatabase
{
    use FrameworkRefreshDatabase {
        refreshTestDatabase as frameworkRefreshTestDatabase;
    }

    /**
     * Refresh a conventional test database.
     *
     * This is a drop-in replacement for Laravel's `RefreshDatabase` testing trait. Do not use them together.
     *
     * We are having migrations targeting two different database connections. The default one "mysql" and another one
     * named "addresses". The `migrate:fresh` command used in the original trait, only drops the tables the default
     * connection. The `--database` option has no use here as it will cause all migrations run against that connection.
     *
     * To workaround the issue, this method calls drops the tables in additionally specified connections which should be
     * stored in test class's `$connectionsToReset` property. Just as Laravel's `$connectionsToTransact` works.
     *
     * More information:
     * https://github.com/laravel/framework/issues/21063
     *
     * @return void
     */
    protected function refreshTestDatabase()
    {
        if (! RefreshDatabaseState::$migrated) {
            $database = $this->app->make('db');

            foreach ($this->connectionsToReset() as $connection) {
                $database
                    ->connection($connection)
                    ->getSchemaBuilder()
                    ->dropAllTables();
            }
        }

        $this->frameworkRefreshTestDatabase();
    }

    /**
     * The database connections that should be reset before running `migrate:fresh` command.
     *
     * @return array
     */
    protected function connectionsToReset(): array
    {
        return $this->connectionsToReset ?? [];
    }
}

All 4 comments

It drops tables in the default database connection, you can use the --database=... options to drop databases on other connections as well.

Working as expected with the database option, thank you.

@themsaid How can I drop the tables from two databases? As far as I can tell --database=... only lets you drop tables from the given database but then omits to do this for the default one.

<?php

namespace Tests\Traits;

use Illuminate\Foundation\Testing\RefreshDatabaseState;
use Illuminate\Foundation\Testing\RefreshDatabase as FrameworkRefreshDatabase;

trait RefreshDatabase
{
    use FrameworkRefreshDatabase {
        refreshTestDatabase as frameworkRefreshTestDatabase;
    }

    /**
     * Refresh a conventional test database.
     *
     * This is a drop-in replacement for Laravel's `RefreshDatabase` testing trait. Do not use them together.
     *
     * We are having migrations targeting two different database connections. The default one "mysql" and another one
     * named "addresses". The `migrate:fresh` command used in the original trait, only drops the tables the default
     * connection. The `--database` option has no use here as it will cause all migrations run against that connection.
     *
     * To workaround the issue, this method calls drops the tables in additionally specified connections which should be
     * stored in test class's `$connectionsToReset` property. Just as Laravel's `$connectionsToTransact` works.
     *
     * More information:
     * https://github.com/laravel/framework/issues/21063
     *
     * @return void
     */
    protected function refreshTestDatabase()
    {
        if (! RefreshDatabaseState::$migrated) {
            $database = $this->app->make('db');

            foreach ($this->connectionsToReset() as $connection) {
                $database
                    ->connection($connection)
                    ->getSchemaBuilder()
                    ->dropAllTables();
            }
        }

        $this->frameworkRefreshTestDatabase();
    }

    /**
     * The database connections that should be reset before running `migrate:fresh` command.
     *
     * @return array
     */
    protected function connectionsToReset(): array
    {
        return $this->connectionsToReset ?? [];
    }
}

Was this page helpful?
0 / 5 - 0 ratings

Related issues

RomainSauvaire picture RomainSauvaire  路  3Comments

lzp819739483 picture lzp819739483  路  3Comments

ghost picture ghost  路  3Comments

fideloper picture fideloper  路  3Comments

kerbylav picture kerbylav  路  3Comments