当前模型与旧版本不兼容

时间:2019-04-09 23:49:43

标签: laravel database-design laravel-migrations

我有以下陈述(我将其描述为历史记录):

  1. 我使用迁移文件 A
  2. 设置了项目女巫<!-- Load Facebook SDK for JavaScript --> <div id="fb-root"></div> <script> window.fbAsyncInit = function() { FB.init({ appId : '2107772995957885' xfbml : true, version : 'v3.2' }); }; (function(d, s, id) { var js, fjs = d.getElementsByTagName(s)[0]; if (d.getElementById(id)) return; js = d.createElement(s); js.id = id; js.src = 'https://connect.facebook.net/en_US/sdk/xfbml.customerchat.js#xfbml=1&version=v2.12&autoLogAppEvents=1'; fjs.parentNode.insertBefore(js, fjs); }(document, 'script', 'facebook-jssdk'));</script> <!-- Your customer chat code --> <div class="fb-customerchat" attribution=setup_tool page_id="123456789" logged_in_greeting="Hi, Thanks for visiting our site. If you have a question, please ask here." logged_out_greeting="Hi, Thanks for visiting our site. Log into FB to ask a question." greeting_dialog_display="fade" greeting_dialog_delay="10" theme_color="#ff7e29"></div> 模型(和User表)
  3. 一段时间后,我向多对多添加了user_modules表,并在迁移文件 B 中的模式更新中被迫初始化此数组。我是通过

    users
  4. 一段时间后,我需要通过在迁移文件 C 和{{1}中的字段User::chunk(100, function($users) { foreach ($users as $user) { $user->userModule()->create(); } }); 中添加软删除(列delete_at)来更新User模型和表}模型。
  5. 然后我开发系统并添加更多迁移,但是新开发人员有时会加入我们的团队,他必须从头开始构建数据库架构,以便他运行$dates=['deleted_at'],但是他在迁移文件 B中遇到错误
  

[Illuminate \ Database \ QueryException(42S22)]
  SQLSTATE [42S22]:找不到列:1054未知列   “ where子句”中的“ users.deleted_at”(SQL:从User中选择*   其中php artisan:migrateusersusers的空序。deleted_at递增限制100   偏移0)

因此当前的users模型与巫婆迁移文件 B

不兼容

如何处理这种情况?

我在哪里犯了错误,以及将来如何防止这种情况发生?

2 个答案:

答案 0 :(得分:3)

这是由于软删除。将特征SoftDeletes添加到模型时,它将自动向所有查询添加where users.deleted_at is null。解决此问题的最佳方法是在迁移B中向查询中添加withTrashed()

为此,请在迁移B中更改查询,如下所示。这应该删除它试图访问不存在的deleted_at列的部分。毕竟,这种迁移并不知道您以后要添加软删除,因此访问所有用户(包括已删除的用户)非常合理。

User::withTrashed()->chunk(100, function($users) {
    foreach ($users as $user) {
        $user->userModule()->create();
    }
});

在运行迁移之前,您总是可以在用户模型上注释掉SoftDelete特性,但这是一个临时解决方案,因为您需要向所有未来的开发人员进行解释。另外,有时运行php artisan migrate:fresh可能非常方便。您不需要每次都记住要注释掉该特征,因此添加withTrashed()似乎是我最想要的解决方案。

最后,我强烈建议为您的迁移添加种子。迁移应用于架构更改。在这种情况下,我将使用控制台命令或控制台命令的组合。

例如,您可以创建一个由php artisan check:user-modules触发的控制台命令。在此命令中,您可能具有以下内容,仅当尚不存在用户模块时才创建该用户模块。

User::chunk(100, function($users) {
    foreach ($users as $user) {
        if (!$user->userModule()->exists()) {
            $user->userModule()->create();
        }
    }
});

您应该可以随时运行此命令,因为它不会覆盖现有的用户模块。

答案 1 :(得分:0)

替代答案:在这种情况下,我们需要在数据库模式更改后生成或转换某些数据-我们不应使用模型(将来可以独立更改),而应使用{{3} }:

DB::table('users')->chunkById(100, function ($users) {
    foreach ($users as $user) {
        DB::table('user_modules')->insert(
            ['user_id' => $user->id, 'module_id' => 1]
        );
    }
});

正如用inserts/updates编写的那样,播种器设计用于对测试数据进行数据播种,而不用于数据转换-因此,迁移文件可能是放置转换代码(可以在其中生成或更改某些生产数据的好地方)模式更新后的数据库)

  

Laravel提供了一种使用种子类为数据库填充测试数据的简单方法。