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

问题描述 投票:54回答:15

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

migration laravel laravel-4
15个回答
48
投票

看起来你做错了。

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

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

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

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

编辑:

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

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

2013_01_20_221554_table

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

2013_01_19_221554_myFirstMigration

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

你也可以在qazxsw poi表中更改(减少)qazxsw poi列号;)

然后运行batch


1
投票

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

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


0
投票

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


0
投票

我在第1行使用了返回,因此之前的dbs保持不变。

migrations

0
投票

这是我使用的糟糕方法..我将删除除我要迁移的特定文件之外的其他迁移文件,然后在迁移完成后运行PHP artisan migrate我将转到我的垃圾箱并恢复已删除的文件


0
投票

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

你现在可以运行:php artisan migrate(作为回答<?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'); } }

因为php artisan migrate --path=/database/migrations/my_migration.php现在包含以下代码:here(参见Illuminate\Database\Migrations\Migrator::getMigrationFiles()。)


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

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

return Str::endsWith($path, '.php') ? [$path] : $this->files->glob($path.'/*_*.php');

我们必须将它作为the source code(可以作为/** * 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(); } } 访问)注册到容器中,因为这是Migrate命令在将自身注册到IoC时访问它的方式。为此,我们将此代码放入服务提供者(在我的例子中,它是一个'migrator'):

$app['migrator']

然后你可以运行这个:

DatabaseServiceProvider

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

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

为什么?

对于任何感兴趣的人:usecase正在更新数据库的版本及其数据。

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

要执行此类操作,首先必须将用户加载到内存中;然后运行迁移以删除旧列并添加新列;然后为每个用户分配php artisan migrate --path=[database/migrations/my_migration.php,database/migrations/another_migration.php]并保存用户。 (我在这里简化,但你可以想象其他场景)

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

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

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


最后说明:我想将这个答案发布到问题MigrateCommand,因为它是Laravel 5特有的。但我不能 - 因为那个问题被标记为这个问题的副本(尽管这个问题被标记为Laravel 4)。


0
投票

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

  1. 创建您的迁移。
  2. 检查您的迁移状态,如:Migrator
  3. 复制新迁移的全名,并执行以下操作:How can I run specific migration in laravel
  4. 然后做这个php artisan migrate:status

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


37
投票

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


24
投票

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

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

22
投票

运行Laravel 4迁移php artisan migrate --pretend时,一个很好的小片段可以缓解任何恐惧。这将仅输出在运行实际迁移时已运行的SQL。

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

建议:确保你的所有up()和down()都按照你期望的方式工作。我喜欢在运行迁移时运行up(),down(),up(),只是为了测试它们。如果你没有麻烦地进行5-6次迁移并且意识到你无法将它们回滚,那将是非常糟糕的,因为你没有将down()与up()100%匹配。

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


15
投票

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

然后再次运行php artisan migrate。


4
投票

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

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,并且它将逐步完成一次迁移。


2
投票

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

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

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

祝好运


1
投票

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

对于我的情况,我有几个迁移,其中一个包含应用程序设置。

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

肮脏的解决方法,但它的工作原理......

© www.soinside.com 2019 - 2024. All rights reserved.