【问题标题】:Wrong migration called错误的迁移称为
【发布时间】:2020-12-27 17:25:51
【问题描述】:

我有 2 个迁移,第一个具有以下名称 2019_11_06_171637_create_settings_table.php 和结构:

class CreateSettingsTable extends Migration
{
  public function up()
  {
    Schema::create('settings', function (Blueprint $table) {
      //code
    });
  }
  //function down
}

第二个具有以下名称2020_07_08_246856_create_settings_table.php 和结构:

class CreateAnotherSettingsTable extends Migration
{
  public function up()
  {
    Schema::create('another_settings', function (Blueprint $table) {
      //code
    });
  }
  //function down
}

当我运行 php artisan migrate 时,所有迁移都运行良好,直到 Migrating: 2020_07_08_246856_create_settings_table - 它正在尝试运行 previos 迁移 (2019_11_06_171637_create_settings_table.php) 并引发异常 Table 'settings' already exists

这是否意味着迁移文件的名称在日期和数字之后必须是唯一的?

【问题讨论】:

  • 能否将第二个文件重命名为2020_07_08_246856_create_another_settings_table.php?如果我没记错的话,它会使用文件名来查找正确的类名。
  • @Douwe de Haan,是的,你是对的!重命名对我来说有点问题,因为我尝试合并来自两个项目的迁移,但没有其他方法,谢谢。
  • @hehoboy 我添加了一个答案,因此您可以将其标记为已接受。如果无法重命名,可以尝试将多个迁移合并到一个文件中,这样您就可以将其作为一个迁移运行(如果您不必将历史记录保留在版本控制中)。
  • @hehoboy 添加到我之前的评论中:Laravel 8(昨天发布)具有迁移压缩,可能会解决一些迁移问题 (documentation here)

标签: laravel laravel-migrations


【解决方案1】:

我在某处读到 Laravel 使用迁移的文件名来调用正确的迁移类。我试图查找有关此的一些文档或参考,但我再也找不到了。您当前有两次相同的文件名(如果您忽略时间戳部分),这会导致 Laravel 两次调用同一个类。

如果您将第二个文件(具有 CreateAnotherSettingsTable 类的文件)重命名为 2020_07_08_246856_create_another_settings_table.php,您的问题将得到解决。

【讨论】:

    【解决方案2】:

    我觉得这很有趣,所以我查看了源代码。

    \Illuminate\Database\Console\Migrations\TableGuesser 将使用迁移名称来判断表是否已经存在。

            // Next, we will attempt to guess the table name if this the migration has
            // "create" in the name. This will allow us to provide a convenient way
            // of creating migrations that create new tables for the application.
            if (! $table) {
                [$table, $create] = TableGuesser::guess($name);
            }
    

    这是在artisan:makemigrate:install 命令上执行的。

    因此,最终,由于您的迁移文件名为 create_settings_table.php,因此“设置”一词将用于检查。

    laravel 用来判断的代码是:

        const CREATE_PATTERNS = [
            '/^create_(\w+)_table$/',
            '/^create_(\w+)$/',
        ];
    
        const CHANGE_PATTERNS = [
            '/_(to|from|in)_(\w+)_table$/',
            '/_(to|from|in)_(\w+)$/',
        ];
    
        /**
         * Attempt to guess the table name and "creation" status of the given migration.
         *
         * @param  string  $migration
         * @return array
         */
        public static function guess($migration)
        {
            foreach (self::CREATE_PATTERNS as $pattern) {
                if (preg_match($pattern, $migration, $matches)) {
                    return [$matches[1], $create = true];
                }
            }
    
            foreach (self::CHANGE_PATTERNS as $pattern) {
                if (preg_match($pattern, $migration, $matches)) {
                    return [$matches[2], $create = false];
                }
            }
        }
    

    因此,您的解决方案是重命名这些迁移文件之一。

    CreateAnotherSettingsTable 将是最好的,标准的追随者,名字

    【讨论】:

      猜你喜欢
      • 2013-07-09
      • 2014-06-03
      • 2022-10-21
      • 1970-01-01
      • 2013-02-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多