运行一个特定的Laravel迁移(单个文件)


72

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


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

3
php artisan migrate --path="app/database/migrations/my_single_migration"
杰夫·普基特

Answers:


52

看来您做错了。

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

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

如果您确实需要执行数据库中的某些操作,则最好创建一个DDL脚本并在Web服务器上手动执行它。

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

编辑:

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

如果只需要对它们重新排序,则将文件重命名为第一个。迁移是使用timestemp创建的:

2013_01_20_221554_table

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

2013_01_19_221554_myFirstMigration

3
是的,您说的很清楚,但是在您的评论结尾,我看到:“或者只是创建一个新的迁移并使用工匠来执行它。” 我创建了一个新迁移,我想运行它。如果执行:artisan migration,此命令将运行我的所有迁移,而不是我创建的新迁移。
Mamadou13年

1
我不打算重新安排我的迁移。我在项目开始时创建了五个迁移。几周后,我看到我需要一个新表,因此我创建了一个新迁移。我要运行此命令以添加新表及其结构。我不明白为什么我应该重新运行已经执行的迁移,而不是重新运行我创建的新迁移?
Mamadou13年

4
如果要迁移数据库,然后添加新的迁移,只需再次运行artisan migrate命令。它将迁移所有未迁移的迁移,它们的创建顺序相同。
Lance Pioch

12
-1是因为“看起来您做错了”。恕我直言,Laravel做错了。开发<>生产。这两种环境要求不同类型的担保和安全措施,并且如果遵循不同的纪律,这是完全合法的。开发首先需要灵活性,而开发人员可能需要根据自己的需要调整迁移机制。我本人非常想念这种灵活性,并求助于直接数据库操作,以获取我想要的东西,这种东西在生产中永远不会发生,但在开发中经常发生。
Ashkan Kh。Nazary

1
@ ashy_32bit我不同意您的意见,因为Laravel并没有做错任何事情。规则是“永远不要编辑在生产环境中执行的迁移”。但是您可以按照自己认为合适的任何方式来编辑本地迁移。
pedromanoel 2015年

41

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


2
尝试过这一点,这是一个很好的选择,但我不知道在回滚时是否会遇到问题
Diamond

是@Diamond,像基于插件的模块时,需要卸载,那么它可能是一个大问题回滚..
Tamaghna班纳吉

38

您可以将迁移放入更多文件夹中,然后运行以下命令:

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

25

一个不错的小片段,可减轻运行Laravel 4迁移时的任何恐惧php artisan migrate --pretend。如果您运行实际的迁移,这只会输出将要运行的SQL。

听起来您的初始4迁移已经运行。我猜想当您php artisan migrate将仅运行新的最新迁移时。

忠告:确保您的所有up()和down()都能按预期运行。我在运行迁移时喜欢运行up(),down(),up(),只是为了对其进行测试。您要进行5-6次迁移,并意识到您无法毫不费力地回滚它们,将是很糟糕的,因为您没有将down()与up()100%匹配。

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


--pretend有一个缺点。在updown方法中,如果查询数据库,它将不返回任何记录。
Binar Web

16

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

然后再次运行php artisan migration。


2
您还可以设置“批处理”字段-laravel一次运行(并回滚)一个批处理迁移,因此您只需更改批号即可回滚单个迁移。
Benubird 2014年

我们无法对迁移表执行此操作This table does not contain a unique column. Grid edit, checkbox, Edit, Copy and Delete features are not available.
Chaudhry Waqas

1
好吧,我说这可能取决于您使用的数据库引擎。就我而言,这种方式效果很好。只要您可以手动执行SQL命令,就可以先选择再删除。
elfif

在大多数情况下,是的。但这取决于要重新执行的迁移的复杂性。如果要添加表,并且没有其他迁移依赖于更改同一表,可以,只需手动删除该表,然后删除迁移表中与要运行的迁移相对应的行。这就是设计表时如何使用迁移功能的方式。由于这是最新/最新/最新的迁移,因此以这种方式轻松完成并可以正常工作。
phpguru

6

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

mkdir /database/migrations/my_migrations

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

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

希望这可以帮助!


3

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

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

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

之后,您可以artisan migrate:rollback根据需要进行任意操作,并且它将一次完成一次迁移。


3

我知道有一种简单的方法只能在本地主机上使用

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

这种方法是完全安全的,不会出现任何错误或问题,尽管看起来像非专业方法,但仍然可以正常工作。

祝好运


1

如果仅出于测试目的,这就是我的方法:

就我而言,我有几次迁移,其中之一包含App-Settings。

当我测试应用程序时,并不是所有迁移都已经安装完毕,我只是将它们移到新文件夹“ future”中。工匠不会触碰此折页,它只会执行您想要的迁移。

肮脏的解决方法,但它可以工作...


1

如果要运行最新的迁移文件,请执行以下操作:

php artisan migrate

您还可以使用以下方法恢复到添加迁移之前的状态:

php artisan migrate: rollback

1

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

  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();
        });
    }

您也可以batchmigrations表中更改(减少)列号;)

然后运行php artisan migrate



1

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

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

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


0

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


0

我在第1行使用return,因此先前的数据库保持原样。

<?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');
    }
}

0

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


0

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

现在,您可以运行这个命令: php artisan migrate --path=/database/migrations/my_migration.php (如回答在这里

因为Illuminate\Database\Migrations\Migrator::getMigrationFiles()现在包含此代码: return Str::endsWith($path, '.php') ? [$path] : $this->files->glob($path.'/*_*.php');的源代码


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

因此,我采用了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']),因为这是当Migrate命令将其自身注册到IoC时对其进行访问的方式。为此,我们将以下代码放入服务提供商中(在我的情况下为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兼容。

为什么?

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

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

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

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

为此,我需要上述机制并定义一组固定的迁移要运行,以使此命令起作用。

注意:我本来希望使用一个简单的装饰器来利用magic__call方法,并避免继承(Laravel在\Illuminate\Database\Eloquent\Builder包装时使用的类似机制 \Illuminate\Database\Query\Builder),但是MigrateCommand可悲的是Migrator,它需要在其构造函数中有一个实例。


最后说明:我想将这个问题的答案发布到如何在laravel中运行特定的迁移,因为它是Laravel 5特有的。但是我不能-因为该问题被标记为该问题的重复(尽管该问题被标记为Laravel 4)。


0

您可以键入以下命令:

PHP Artisan Migration-帮助

...

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

...

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

php artisan migration --path = /数据库/migrations/v1.0.0/

其中“ v.1.0.0”是位于“ / database / migrations”目录下的目录,其中包含要针对特定​​版本运行的那些迁移。

如果没有,那么您可以在迁移表中签入,查看已经运行了哪些迁移,如下所示:

选择*从迁移;

然后将已执行的文件夹移出“ / database / migrations”文件夹。通过创建另一个文件夹“ / databases / exected-migrations”并将已移至。

之后,您应该能够执行:

PHP的工匠迁移

无需任何危险即可覆盖架构/数据库中的任何现有表。


0

如果要在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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.