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

时间:2013-09-30 19:27:05

标签: migration laravel laravel-4

我不想在laravel 4上运行All Outstanding Migrations。我有5次迁移。现在我只想运行一次迁移。  而不是做:php artisan migrate 我想运行一个特定的迁移,如:php artisan migrate MY_MIGRATION_TO_RUN

19 个答案:

答案 0 :(得分:47)

看起来你做错了。

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

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

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

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

编辑:

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

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

2013_01_20_221554_table

要在此之前创建新的迁移,您可以将其命名为

2013_01_19_221554_myFirstMigration

答案 1 :(得分:36)

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

答案 2 :(得分:22)

在运行Laravel 4迁移php artisan migrate --pretend时,可以轻松解决任何恐惧的小片段。这将仅输出在您运行实际迁移时已运行的SQL。

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

建议提示:确保所有up()和down()都按预期运行。我喜欢在运行迁移时运行up(),down(),up(),只是为了测试它们。 你很难获得5-6次迁移并意识到你不能轻易地回滚它们,因为你没有将down()与up()100%匹配。

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

答案 3 :(得分:18)

您可以将迁移放在更多文件夹中,并执行以下操作:

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

答案 4 :(得分:15)

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

然后再次运行php artisan migrate。

答案 5 :(得分:4)

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

mkdir /database/migrations/my_migrations

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

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

希望这有帮助!

答案 6 :(得分:3)

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

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

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

在此之后,您可以根据需要artisan migrate:rollback,并逐步完成一次迁移。

答案 7 :(得分:2)

我知道这样做的一种简单方法只能在本地主机

上为您提供
  1. 根据需要修改您的迁移文件
  2. 打开您的phpMyAdmin或用于查看数据库表的任何内容
  3. 找到所需的表并将其删除
  4. 查找迁移表并将其打开
  5. 在迁移字段下的此表中
  6. 找到您想要的表名并删除其行
  7. 最后从命令行或终端运行命令max_columns。这只会迁移数据库中迁移表中不存在的表。
  8. 这种方式是完全安全的,不会出现任何错误或问题,虽然它看起来像非专业的方式,但它仍然可以完美地运作。

    祝你好运

答案 8 :(得分:1)

如果它仅用于测试目的,我就是这样做的:

对于我的情况,我有几次迁移,其中一次包含App-Settings。

虽然我正在测试应用程序并且并非所有迁移都已设置,但我只是将它们移动到新文件夹“future”。技术人员不会触及此片段,它只会执行您想要的迁移。

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

答案 9 :(得分: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();
        });
    }

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

然后运行php artisan migrate

答案 10 :(得分:0)

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

答案 11 :(得分: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

答案 12 :(得分:0)

您可以键入以下命令:

  

php artisan migration --help

...

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

...

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

  

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

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

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

  

SELECT * FROM迁移;

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

之后,您应该可以执行:

  

php artisan迁移

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

答案 13 :(得分:0)

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

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

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

答案 14 :(得分:0)

对于仍然对此感兴趣的任何人,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->files->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']的身份访问),因为这是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兼容。

为什么?

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

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

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

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

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

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


最后说明:我想将这个答案发布到问题How can I run specific migration in laravel上,因为它是Laravel 5特有的。但是我不能-因为该问题被标记为该问题的重复(尽管该问题被标记为Laravel 4)。

答案 15 :(得分:0)

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

答案 16 :(得分: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');
    }
}

答案 17 :(得分:0)

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

使用这种方法,您可以将一堆迁移分成几个步骤。

答案 18 :(得分:-1)

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