在 Laravel 中回滚一个特定的迁移

491

我希望

仅回滚:

已回滚:2015_05_15_195423_alter_table_web_directories


我运行

php artisan migrate:rollback,我的3个迁移正在回滚。

Rolled back: 2015_05_15_195423_alter_table_web_directories
Rolled back: 2015_05_13_135240_create_web_directories_table
Rolled back: 2015_05_13_134411_create_contacts_table

我删掉了

我无意中删除了我的web_directoriescontacts表。我从未想过这种情况会发生,如果我能够回滚到特定的时间点,那么这场灾难就不会发生。


91
点赞!只是因为您写这个问题的方式很好 :) - Sliq
1
我正在使用 sqlpro,它允许我更改批号,所以我只是更改了数字并回滚。 - Rolly
考虑到未来的回滚,使用“php artisan migrate --step”逐步运行每个迁移,这样当您运行“php artisan migrate:rollback”时,只会回滚一个迁移。 - James
公告:请停止添加与顶部答案完全相同的答案,可以使用“rollback --step”进行回滚。 - General Grievance
29个回答

467

Laravel 5.3+

本地回滚一步。

php artisan migrate:rollback --step=1

这里是手册页面:docs


Laravel 5.2 及之前版本

没有简便的方法。详情请参考 Martin Bean 的 答案


1
除非原始问题(OP)使用正在开发中的Laravel版本编写他的应用程序,否则此内容无用。 - Martin Bean
5
这是一个不错的功能,但缺少指定要回滚哪个迁移的功能。我猜它只会回滚迁移表中列出的最后一个?当我迁移东西时,通常没有计划回滚,所以我想要回滚的迁移是最后一个迁移的机会并不是很高。似乎laravel在这方面有点失误。我想唯一安全的回滚单个迁移的方法就是手动编辑迁移表了。 - Skeets
@SkeetsO'Reilly 同意,迁移并没有被非常好地考虑。但是它们在这里,所以你不必从一开始就寻找迁移包。 - Yauheni Prakopchyk
它像魔法一样奏效。我正在开发一个新的迁移(向现有表添加列),然后我看到我使用了“uuid”类型进行迁移,但我想要“string”类型。您的回滚提示完美地解决了这个问题。回滚。更新代码。再次迁移。=> 100%正常。Laravel 5.7 - Florian Doyen
如何通过(php artisan)命令行获取我的最后N个迁移步骤?如果我想要,我可以查找我的迁移表并查询以获取我的历史记录和最后运行的迁移。但是,另一方面,我不能总是使用我的迁移文件夹,因为新的迁移不总是排序的。针对这个问题,我建议我们使用“php artisan make:migration”,而不使用现有文件中间的迁移文件副本。 - saber tabatabaee yazdi

342

如果你查看你的 migrations 表,你会发现每个迁移都有一个批次号。因此,当你回滚时,它会回滚上一批次中所包含的每个迁移。

如果你只想回滚最后一个迁移,那么只需将批次号增加一即可。然后下次运行 rollback 命令时,它只会回滚该迁移,因为它是自己的“批次”。

另外,从 Laravel 5.3 开始,你可以直接运行:

php artisan migrate:rollback --step=1

无论迁移的批次号是什么,这将回滚最后一次迁移。


好的建议!我试图编辑批次编号,但它不允许我这样做。它有点像被锁住了,并且是灰色的。我在我的Mac上尝试使用MySQL WorkBench。对此有什么想法吗? - code-8
你知道为什么我在尝试配置时,我的批次号被锁定了吗? - code-8
2
通过以下查询在迁移表中更新批次号:UPDATE migrations SET batch=2 WHERE migration='name_of_the_migration'; - Imran Khan
4
如果你有超过两个批次,将批次号硬编码为“2”并不是一个特别好的做法。 - Martin Bean
你无法编辑行(我假设在phpMyAdmin中)的原因是迁移表没有索引。你将不得不采用手动SQL语句,就像@ImranKhan的评论中所述。我使用例如... WHERE migration LIKE '2019_01%'。我希望有更好的编程方式来分组迁移。 - 4levels
显示剩余5条评论

55

最好的方式是创建一个新的迁移,对其进行所需的更改。

最坏情况下的解决办法(如果您可以访问数据库并且您不介意重置该表的数据):

  1. 进入数据库,删除/rename your-specific-migration 的迁移条目
  2. 删除your-specific-migration 创建的表
  3. 运行 php artisan migrate --path=/database/migrations/your-specific-migration.php

这将强制 laravel 运行该特定迁移,因为 Laravel 的迁移历史记录中没有关于它的条目

更新: Laravel 方式(感谢 @thiago-valente)

运行:

php artisan migrate:rollback --path=/database/migrations/your-specific-migration.php

然后运行:

php artisan migrate

这将重新运行该特定迁移


13
我使用了以下命令: php artisan migrate:rollback --path=/database/migrations/your-specific-migration.php 最后执行了以下命令: php artisan migrate - Thiago Valente
我认为这是重新运行迁移的最佳方式,感谢您的答复。 - CodeFluid

32

每次回滚操作都会获取最后一批迁移记录。 使用以下命令:

php artisan migrate:rollback --step=1

32

最好使用refresh migrate

您可以通过向刷新命令提供步骤选项来回滚和重新迁移有限数量的迁移。例如,以下命令将回滚并重新迁移最后两个迁移:

php artisan migrate:refresh --step=2

否则使用回滚迁移

您可以通过在回滚命令中提供步骤选项来回滚有限数量的迁移。例如,以下命令将回滚最近的三个迁移:

php artisan migrate:rollback --step=3

有关迁移的更多详细信息,请参见


在 Laravel 中,回滚是什么意思? - vishal

27

如果你无法按照@Martin Bean的指示去做,那么可以尝试另一种方法。

创建一个新的迁移,在其中的up()方法中插入你想要回滚的migration文件中down()方法的内容,在down()方法中插入up()方法的内容。

例如,如果你原来的migration如下:

public function up()
{
    Schema::create('users', function(Blueprint $table)
    {
        $table->increments('id')->unsigned();
        $table->string('name');
    });
}
public function down()
{
    Schema::drop('users');
}

然后在新的迁移文件中执行以下操作

public function up()
{
    Schema::drop('users');
}
public function down()
{
    Schema::create('users', function(Blueprint $table)
    {
        $table->increments('id')->unsigned();
        $table->string('name');
    });
}

然后运行迁移,它将删除表格。 如果你想要恢复它,只需回滚即可。


谢谢你的回答,但我已经解决了。我有一个快速问题想问你,你知道为什么我不能编辑我的迁移表的批处理列吗? - code-8
2
@ihue,有点晚了,但你无法使用UI编辑的原因是表迁移没有主键。你必须自己编写SQL来进行编辑。 - Vic
非常聪明,它做到了我想要的。 - Gjaa
我认为这是最好的做法。 - Yousef Altaf
我喜欢这个,值得点赞 :).. 我认为更好的方法是有两个迁移。一个是删除现有表,另一个是创建新表。第一个将在回滚时重新创建表,而第二个将删除新表。 - Keith Mifsud

18

你可以使用

php artisan migrate:rollback --path=/database/migrations/timestamp_filename.php

这将删除特定的迁移。如果该文件具有外键依赖关系,请使用drop方法。对于这些情况,请尝试创建新的迁移并在需要时删除外键。


1
这是最安全的选择。 - Wayne Smallman

15

试试这个:

php artisan migrate:rollback --step=1

这适用于 Laravel 5.3及以上版本。


11
如果您可以访问数据库,那么您有一个更简单的解决方案。您可以从migrations表中删除记录,然后使用SQL客户端仅删除该表。
或者可以使用
php artisan migrate:rollback --path=... 

像许多答案一样。并记住路径是位置。您可以像这样删除甚至模块迁移。(来自任何地方的任何迁移)

php artisan migrate:rollback --path=Modules/YourModule/database/migrations/2020_05_15_xxxxxx_create_your_table.php

记住,如果您使用Linux服务器,请注意区分大小写。您必须像这样添加 /Database/Migrations ,以大写字母开头。


/Database/Migrations/2020_05_15_xxxxxx_create_your_table.php

9

也许回答这个问题有点晚了,但我觉得下面的方法非常好、干净、高效。我会尽可能详细地说明。

在创建迁移之前,请按照以下方式创建不同的目录:

    database
       | 
       migrations
            |
            batch_1
            batch_2
            batch_3

然后,在创建迁移时运行以下命令(使用您的表作为示例):

     php artisan make:migration alter_table_web_directories --path=database/migrations/batch_1

或者

     php artisan make:migration alter_table_web_directories --path=database/migrations/batch_2

或者

     php artisan make:migration alter_table_web_directories --path=database/migrations/batch_3

以上命令将在给定的目录路径中创建迁移文件。然后,您只需运行以下命令,即可通过它们分配的目录迁移您的文件。

    php artisan migrate alter_table_web_directories --path=database/migrations/batch_1

*注意:您可以将batch_1更改为batch_2或batch_3或任何您存储迁移文件的文件夹名称。只要它仍然在database / migrations目录或某个指定目录中即可。
接下来,如果您需要回滚特定的迁移,则可以按批次回滚,如下所示:
    php artisan migrate:rollback --step=1
                    or try
php artisan migrate:rollback alter_table_web_directories --path=database/migrations/batch_1

或者

    php artisan migrate:rollback --step=2
                    or try
php artisan migrate:rollback alter_table_web_directories --path=database/migrations/batch_2

或者
    php artisan migrate:rollback --step=3
                    or try
php artisan migrate:rollback alter_table_web_directories --path=database/migrations/batch_3

使用这些技术将允许您更灵活地控制您的数据库和对模式所做的任何修改。


除非laravel文档有误,"--step=3"的意思是回滚最后三个迁移,而不是回滚第三个最近运行的迁移。我不知道将迁移放在不同的文件夹中是否会改变这一点,但我不会期望它会改变。如果指定名称回滚有效,那就太好了!然而,如果给回滚任何参数,它会抱怨"参数过多"。 - Skeets

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接