【问题标题】:Running one specific Laravel migration (single file)运行一个特定的 Laravel 迁移(单个文件)
【发布时间】:2023-04-08 04:41:01
【问题描述】:

我不想在 laravel 4 上运行所有未完成的迁移。我有 5 个迁移。现在我只想运行一次迁移。 而不是这样做:php artisan migrate 我想运行一个特定的迁移,例如:php artisan migrate MY_MIGRATION_TO_RUN

【问题讨论】:

  • 我也有同样的用例。应该有这样的选择。我需要运行迁移,然后是大型 etl 脚本,然后运行迁移的后半部分。在运行 etl 脚本之前,第二个文件不应该在我的代码库中是没有意义的。

标签: migration laravel laravel-4


【解决方案1】:

看起来你做错了。

迁移由 Laravel 逐一执行,按照它们创建的确切顺序,因此它可以跟踪执行和执行顺序。这样,Laravel 将能够安全地回滚一批迁移,而不会有破坏数据库的风险。

赋予用户手动执行它们的权力,让用户无法(确定)知道如何回滚数据库中的更改。

如果你真的需要在你的数据库中执行某些东西,你最好创建一个 DDL 脚本并在你的网络服务器上手动执行它。

或者只是创建一个新的迁移并使用 artisan 执行它。

编辑:

如果你需要先运行它,你需要先创建它。

如果您只需要重新排序,请将文件重命名为第一个。迁移是使用时间创建的:

2013_01_20_221554_table

要在此之前创建一个新迁移,您可以命名它

2013_01_19_221554_myFirstMigration

【讨论】:

  • 是的,你说的很清楚,但在你的评论结尾我看到:“或者只是创建一个新的迁移并使用工匠执行它。”我创建了一个新的迁移,我想运行它。如果我这样做:artisan migrate,这个命令将运行我所有的迁移,而不是我创建的新迁移。
  • 我不想重新排序我的迁移。我在项目开始时创建了五个迁移。几周后,我发现我需要一个新表,所以我创建了一个新的迁移。我想运行它来添加新表及其结构。我不明白为什么我应该重新运行我已经执行的迁移,而不仅仅是我创建的新迁移?
  • 如果您迁移数据库,然后添加新的迁移,只需再次运行 artisan migrate 命令。它将按照创建顺序迁移所有未迁移的迁移。
  • -1 因为“看起来你做错了”。恕我直言,Laravel 做错了。开发生产。这两种环境需要不同类型的保证和安全措施,如果它们遵循不同的规则是完全合法的。开发首先需要灵活性,开发人员可能需要根据自己的需要调整迁移机制。我自己非常想念这种灵活性,并求助于直接的数据库操作来获得我想要的东西,这在生产中永远不会发生,但在开发中经常发生。
  • @ashy_32bit 我不同意你的观点,因为 Laravel 并没有做错什么。规则是“永远不要编辑在生产中执行的迁移”。但是您可以以任何您认为合适的方式编辑本地迁移。
【解决方案2】:

一个不错的小 sn-p 可以缓解运行 Laravel 4 迁移 php artisan migrate --pretend 时的任何恐惧。如果您运行实际迁移,这只会输出本应运行的 SQL。

听起来您最初的 4 次迁移已经运行。我猜当你 php artisan migrate 时,它只会运行新的、最近的迁移。

忠告:确保您的所有 up() 和 down() 都按照您的预期工作。我喜欢在运行迁移时运行 up()、down()、up(),只是为了测试它们。 如果您进行 5-6 次迁移并意识到您无法轻松回滚它们,那将是非常糟糕的,因为您没有将 down() 与 up() 100% 匹配。

只要我的两分钱!希望--pretend 有所帮助。

【讨论】:

  • --pretend 有一个缺点。在updown这两种方法中,如果查询数据库,都不会返回任何记录。
  • @BinarWeb 我遇到了这个问题。对于这里的其他人,如果您需要通过 select 查询数据库以获取插入另一个表或其他内容的外键,则不会返回任何结果。如果您试图返回一个对象,例如。用户,并且您尝试更新其上的字段,您可能会收到类似Creating default object from empty value 的错误。迁移中的所有查询都在类似于回滚的事务中运行,尽管可能不是字面意思。
【解决方案3】:

重新运行迁移的唯一方法是脏迁移。您需要打开数据库并删除迁移表中代表您的迁移的行。

然后再次运行 php artisan migrate。

【讨论】:

  • 您还可以设置“batch”字段 - laravel 一次运行(并回滚)迁移,因此您只需更改批次号以允许回滚单个迁移。跨度>
  • 我们不能对迁移表执行此操作This table does not contain a unique column. Grid edit, checkbox, Edit, Copy and Delete features are not available.
  • 好吧,我说这可能取决于您使用的数据库引擎。就我而言,这种方式效果很好。只要您可以手动执行 SQL 命令,您就可以先选择然后删除。
  • 在大多数情况下,是的。但这取决于您要重新执行的迁移的复杂性。如果它正在添加一个表并且没有其他迁移依赖于更改同一个表,是的,只需手动删除该表,删除迁移表中与您要运行的迁移相对应的行。这就是我在设计表格时使用迁移功能的方式。由于这是最后一次/最新/最新的迁移,因此以这种方式进行操作非常简单,而且效果很好。
【解决方案4】:

只需将已运行的迁移移出 app/config/database/migrations/ 文件夹即可。然后运行命令 php artisan migrate 。对我来说就像一个魅力。

【讨论】:

  • 试过了,这是一个很好的,但如果我在回滚时遇到问题,我不会这样做
  • 是的@Diamond,对于基于插件的模块,当需要卸载时,回滚可能是个大问题..
【解决方案5】:

如果只是为了测试目的,我就是这样做的:

就我而言,我有几个迁移,其中一个包含应用程序设置。

虽然我正在测试应用程序,但并非所有迁移都已设置好,我只是将它们移动到“未来”的新文件夹中。此折叠不会被工匠触及,它只会执行您想要的迁移。

肮脏的解决方法,但它有效......

【讨论】:

    【解决方案6】:

    我在另一篇文章中给出了这个答案,但您可以这样做:运行 artisan migrate 运行所有迁移,然后使用以下 SQL 命令更新迁移表,使其看起来像一次运行一个迁移:

    SET @a = 0;  
    UPDATE migrations SET batch = @a:=@a+1;
    

    这会将批处理列更改为 1、2、3、4 .. 等。如果您只想影响某些迁移,请在此处添加 WHERE batch>=... 条件(并更新 @a 的初始值)。

    之后,您可以根据需要artisan migrate:rollback,它会一步一步完成迁移。

    【讨论】:

    • 这是迄今为止最好的解决方案。我认为上面的查询有点矫枉过正,但基本原理很棒,而且非常简单。为了尽量减少工作量,只需将您想要单独运行的迁移表记录提升到“顶部”即。将其batch 列号更改为表中的最高值。回滚(特别是如果你想测试你的 down() 方法)并重新运行php artisan migrate
    【解决方案7】:

    如果您想运行最新的迁移文件,您可以执行以下操作:

    php artisan migrate
    

    您还可以使用以下命令恢复到添加迁移之前:

    php artisan migrate: rollback
    

    【讨论】:

      【解决方案8】:

      您可以将迁移放在更多文件夹中并运行以下内容:

      php artisan migrate --path=/app/database/migrations/my_migrations
      

      【讨论】:

        【解决方案9】:

        如此简单...!只需转到您的迁移文件夹。将所有迁移文件移动到另一个文件夹中。然后将所有迁移一一返回到迁移文件夹并为其中一个运行迁移(php artisan)。当您将错误的迁移文件插入主迁移文件夹并在命令提示符下运行 php artisan migrate 时会出错。

        【讨论】:

          【解决方案10】:

          我也有同样的问题。 在第一个迁移文件中复制表创建代码,如下所示:

            public function up()
              {
                  Schema::create('posts', function(Blueprint $table){
                      $table->increments('id');
                      // Other columns...
                      $table->timestamps();
                  });
                  Schema::create('users', function (Blueprint $table) {
                      $table->increments('id');
                      // Other columns...
                      $table->softDeletes()->nullable();
                  });
              }
          

          您也可以更改(减少)batch 表中migrations 的列号;)

          然后运行php artisan migrate

          【讨论】:

            【解决方案11】:

            在迁移中抛出异常,如果您不想应用它,它将停止整个迁移过程。

            使用这种方法,您可以将大量迁移拆分为多个步骤。

            【讨论】:

              【解决方案12】:

              据我所知,有一种简单的方法只能在本地主机

              上为您提供
              1. 根据需要修改您的迁移文件
              2. 打开您的 phpMyAdmin 或任何您用来查看数据库表的工具
              3. 找到所需的表并将其删除
              4. 找到迁移表并打开它
              5. 在此表中的迁移字段下找到您想要的表名并删除其行
              6. 最后从命令行或终端运行命令php artisan migrate。这只会迁移数据库中迁移表中不存在的表。

              这种方式是完全安全的,不会出现任何错误或问题,虽然它看起来像不专业的方式,但它仍然可以完美运行。

              祝你好运

              【讨论】:

                【解决方案13】:

                您可以从终端为您的迁移创建一个单独的目录,如下所示:

                mkdir /database/migrations/my_migrations
                

                然后将您要运行的特定迁移移动到该目录并运行此命令:

                php artisan migrate --path=/database/migrations/my_migrations
                

                希望这会有所帮助!

                【讨论】:

                  【解决方案14】:

                  我在第 1 行使用了 return,所以之前的 dbs 保持原样。

                  <?php
                  
                  use Illuminate\Support\Facades\Schema;
                  use Illuminate\Database\Schema\Blueprint;
                  use Illuminate\Database\Migrations\Migration;
                  
                  class CreateUsersTable extends Migration
                  {
                      /**
                       * Run the migrations.
                       *
                       * @return void
                       */
                      public function up()
                      {
                          return;  // This Line
                          Schema::create('users', function (Blueprint $table) {
                              $table->increments('id');
                              $table->string('name', 50);
                              $table->string('slug', 50)->unique();
                              $table->integer('role_id')->default(1);
                              $table->string('email', 50)->unique();
                              $table->timestamp('email_verified_at')->nullable();
                              $table->string('mobile', 10)->unique();
                              $table->timestamp('mobile_verified_at')->nullable();
                              $table->text('password');
                              $table->integer('can_login')->default(1);
                              $table->rememberToken();
                              $table->timestamps();
                          });
                      }
                  
                      /**
                       * Reverse the migrations.
                       *
                       * @return void
                       */
                      public function down()
                      {
                          return;// This Line
                          Schema::dropIfExists('users');
                      }
                  }
                  

                  【讨论】:

                    【解决方案15】:

                    这是我使用的一种不好的方法。我将删除除我要迁移的特定文件之外的其他迁移文件,然后在迁移完成后运行 PHP artisan migrate 我将进入我的垃圾箱并恢复已删除的文件

                    【讨论】:

                      【解决方案16】:

                      对于仍然对此感兴趣的任何人,Laravel 5 更新: Laravel 已经实现了一次运行一个迁移文件的选项(在 5.7 版中)。

                      你现在可以运行这个: php artisan migrate --path=/database/migrations/my_migration.php (回复here

                      因为Illuminate\Database\Migrations\Migrator::getMigrationFiles() 现在包含以下代码: return Str::endsWith($path, '.php') ? [$path] : $this-&gt;files-&gt;glob($path.'/*_*.php');the source code


                      但在我的用例中,我实际上想同时运行一组迁移,而不仅仅是一个或全部

                      所以我采用 Laravel 的方式,注册了一个不同的 Migrator 实现,它决定使用哪些文件:

                      /**
                       * A migrator that can run multiple specifically chosen migrations.
                       */
                      class MigrationsSetEnabledMigrator extends Migrator
                      {
                          /**
                           * @param Migrator $migrator
                           */
                          public function __construct(Migrator $migrator)
                          {
                              parent::__construct($migrator->repository, $migrator->resolver, $migrator->files);
                      
                              // Compatibility with versions >= 5.8
                              if (isset($migrator->events)) {
                                  $this->events = $migrator->events;
                              }
                          }
                      
                          /**
                           * Get all of the migration files in a given path.
                           *
                           * @param  string|array $paths
                           * @return array
                           */
                          public function getMigrationFiles($paths)
                          {
                              return Collection::make($paths)->flatMap(function ($path) {
                                  return Str::endsWith($path, ']') ? $this->parseArrayOfPaths($path) :
                                      (Str::endsWith($path, '.php') ? [$path] : $this->files->glob($path . '/*_*.php'));
                              })->filter()->sortBy(function ($file) {
                                  return $this->getMigrationName($file);
                              })->values()->keyBy(function ($file) {
                                  return $this->getMigrationName($file);
                              })->all();
                          }
                      
                          public function parseArrayOfPaths($path)
                          {
                              $prefix = explode('[', $path)[0];
                              $filePaths = explode('[', $path)[1];
                              $filePaths = rtrim($filePaths, ']');
                      
                              return Collection::make(explode(',', $filePaths))->map(function ($filePath) use ($prefix) {
                                  return $prefix . $filePath;
                              })->all();
                          }
                      }
                      

                      我们必须将它作为'migrator' 注册到容器中(以$app['migrator'] 访问),因为这是在将自身注册到 IoC 时 Migrate 命令访问它的方式。为此,我们将这段代码放入服务提供者中(在我的例子中,它是DatabaseServiceProvider):

                          public function register()
                          {
                              $this->app->extend('migrator', function ($migrator, $app) {
                                  return new MultipleSpecificMigrationsEnabledMigrator($migrator);
                              });
                      
                              // We reset the command.migrate bind, which uses the migrator - to 
                              // force refresh of the migrator instance.
                              $this->app->instance('command.migrate', null);
                          }
                      

                      然后你可以运行这个:

                      php artisan migrate --path=[database/migrations/my_migration.php,database/migrations/another_migration.php]

                      注意多个迁移文件,以逗号分隔。

                      它在 Laravel 5.4 中经过测试和工作,应该与 Laravel 5.8 兼容。

                      为什么?

                      对于任何感兴趣的人:用例是更新数据库版本及其数据

                      例如,假设您想将所有用户的街道和门牌号码合并到新列中,我们称之为street_and_house。想象一下,您想以安全且经过测试的方式在多个安装中执行此操作 - 您可能会为此创建一个脚本(在我的情况下,我创建数据版本控制命令 - 工匠命令)。

                      要进行这样的操作,您首先必须将用户加载到内存中;然后运行迁移以删除旧列并添加新列;然后为每个用户分配street_and_house=$street . " " . $house_no 并保存用户。 (我这里是在简化,但你肯定可以想象其他场景)

                      而且我不想依赖我可以在任何给定时间运行所有迁移的事实。想象一下,您想将它从 1.0.0 更新到 1.2.0,并且有多批这样的更新 - 执行任何更多的迁移可能会破坏您的数据,因为这些迁移必须由它们自己的专用更新命令处理。因此,我只想运行此更新知道如何使用的选定已知迁移,然后对数据执行操作,然后可能运行下一个更新数据命令。 (我想尽可能地防守)。

                      为了实现这一点,我需要上述机制并定义一组固定的迁移以运行这样的命令。

                      注意:我宁愿使用一个简单的装饰器,利用神奇的 __call 方法并避免继承(Laravel 在 \Illuminate\Database\Eloquent\Builder 中使用的类似机制来包装 \Illuminate\Database\Query\Builder),但是 @遗憾的是,987654338@ 在其构造函数中需要Migrator 的实例。


                      最后注:我想将这个答案发布到问题 How can I run specific migration in laravel ,因为它是 Laravel 5 特定的。但我不能——因为这个问题被标记为这个问题的副本(尽管这个问题被标记为 Laravel 4)。

                      【讨论】:

                        【解决方案17】:

                        您可以使用以下解决方案:

                        1. 创建您的迁移。
                        2. 检查您的迁移状态,例如:php artisan migrate:status
                        3. 复制新迁移的全名并执行以下操作:php artisan migrate:rollback --path:2018_07_13_070910_table_tests
                        4. 然后执行此操作php artisan migrate

                        最后,您迁移特定表。 祝你好运。

                        【讨论】:

                          【解决方案18】:

                          您可以输入以下命令:

                          php artisan 迁移 --help

                          ...

                          --path[=PATH] 要执行的迁移文件的路径(允许多个值)

                          ...

                          如果它确实显示了一个名为 "--path" 的选项(如上面的示例),则表示您的 Laravel 版本支持此参数。如果是这样,那么您很幸运可以输入以下内容:

                          php artisan migrate --path=/database/migrations/v1.0.0/

                          “v.1.0.0” 是存在于“/database/migrations”目录下的目录,其中包含您要为某个版本运行的迁移。

                          如果没有,那么您可以检查您的迁移表以查看哪些迁移已运行,如下所示:

                          SELECT * FROM 迁移;

                          然后将那些已执行的文件移出“/database/migrations”文件夹。通过创建另一个文件夹 "/databases/executed-migrations" 并将您执行的迁移移动到那里。

                          在这之后你应该能够执行:

                          php 工匠迁移

                          覆盖架构/数据库中的任何现有表没有任何危险。

                          【讨论】:

                            【解决方案19】:

                            如果您想在 Laravel 中运行(单个文件)迁移,您可以执行以下操作:

                            php artisan migrate --path=/database/migrations/migrations_file_name
                            

                            例如。

                            C:\xampp\htdocs\laravelv3s>php artisan migrate --path=/database/migrations/2020_02_14_102647_create_blogs_table.php
                            

                            【讨论】:

                            • 这项工作为我删除了路径开头的破折号php artisan migrate --path=database/migrations/migrations_file_name
                            【解决方案20】:

                            (*) Windows 示例: php artisan migrate --path=database\migrations\2021_05_18_121604_create_service_type_table.php

                            【讨论】:

                              猜你喜欢
                              • 2010-10-19
                              • 2018-01-10
                              • 2017-09-21
                              • 2021-02-28
                              • 2019-02-25
                              • 1970-01-01
                              • 2014-11-15
                              • 2010-11-21
                              相关资源
                              最近更新 更多