目次
< 記事一覧

【Laravel】migration時のエラー1

FAIL BadMethodCallException Method Illuminate\Database\MySqlConnection::getDoctrineSchemaManager does not exist. at vendor/laravel/framework/src/Illuminate/Macroable/Traits/Macroable.php:115

 

<原因>

getDoctrineSchemaManager() を呼んで “その外部キーがあるか” を判定しているのに、プロジェクトに doctrine/dbal が入っていない(or 対応しないバージョン)
→ DBALが必須。ただしLaravel 12 では使えない。

 

<解決>

DBALを使わない方法へ変更する。

(変更前の記述)

/**
 * Check if a table has a foreign key constraint with a specific name.
 *
 * @param string $table_name
 * @param string $constraint_name
 * @return bool
 */
private function hasForeignKeyConstraint(string $table_name, string $constraint_name): bool
{
    if (Schema::hasTable($table_name)) {
        $connection = Schema::getConnection();
        $schemaManager = $connection->getDoctrineSchemaManager();

        $tableDetails = $schemaManager->listTableDetails($table_name);
        $existingForeignKeys = $tableDetails->getForeignKeys();

        foreach ($existingForeignKeys as $existingForeignKey) {
            if ($existingForeignKey->getName() === $constraint_name) {
                return true;
            }
        }
    }

    return false;
}

 

(変更後ファイル)

/**
* Check if a table has a foreign key constraint with a specific name.
*
* @param string $table_name
* @param string $constraint_name
* @return bool
*/
private function hasForeignKeyConstraint(string $tableName, string $constraintName): bool
{
if (! Schema::hasTable($tableName)) {
return false;
}

$driver = Schema::getConnection()->getDriverName();

if ($driver === 'mysql') {
    $row = DB::selectOne(
        "SELECT CONSTRAINT_NAME
           FROM information_schema.TABLE_CONSTRAINTS
          WHERE TABLE_SCHEMA = DATABASE()
            AND TABLE_NAME   = ?
            AND CONSTRAINT_NAME = ?
            AND CONSTRAINT_TYPE = 'FOREIGN KEY'",
        [$tableName, $constraintName]
    );
    return $row !== null;
}

if ($driver === 'pgsql') {
    // (PostgreSQLの例:必要なら)
    $row = DB::selectOne(
        "SELECT c.conname
           FROM pg_constraint c
           JOIN pg_class t ON c.conrelid = t.oid
           JOIN pg_namespace n ON n.oid = t.relnamespace
          WHERE c.contype = 'f'
            AND t.relname = ?
            AND c.conname = ?
            AND n.nspname = ANY (current_schemas(false))",
        [$tableName, $constraintName]
    );
    return $row !== null;
}

// 他ドライバは必要に応じて追加
return false;
}

 

 

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です