SQLite 在 Migration 中 dropColumn 的一个小坑,哭死你

背景

第一,我们测试的时候使用 SQLite。

第二,一个正在运行的网站,数据库的有一些改变,我们一般是会新添加 migration,如下:

    public function up()
    {
        Schema::table('table_name', function (Blueprint $table) {
            $table->dropColumn('column1');
            $table->integer('column2')->comment('.......');
                        //...等等等
        });
    }
    public function down()
    {
        Schema::table('table_name', function (Blueprint $table) {
            $table->dropColumn('column2');
            $table->tinyInteger('column1');
                        //...等等等
        });
    }

问题

以上代码在 Mysql 上跑没有任何问题,不管是 migrate 还是 migrate:rollback 还是 migrate:refresh,都完美执行。

但是在测试(使用 SQLite)的时候,各种诡异的问题,这个字段不存在,那个字段有问题...

解决方法

每一个操作都放在一个 Schema::table 的闭包里面。

    public function up()
    {
        Schema::table('table_name', function (Blueprint $table) {
            $table->dropColumn('column1');
        });
        Schema::table('table_name', function (Blueprint $table) {
            $table->integer('column2')->comment('.......');
        });
                //...等等等
    }
    public function down()
    {
        Schema::table('table_name', function (Blueprint $table) {
            $table->dropColumn('column2');
        });
        Schema::table('table_name', function (Blueprint $table) {
            $table->tinyInteger('column1');
        });
              //...等等等
    }

好多人遇到这个问题,比如:
https://github.com/laravel/framework/issue...

如果你遇到了,不要大惊小怪。

本作品采用《CC 协议》,转载必须注明作者和本文链接
写文字大部分时候是因为我希望能帮助到你,小部分时候是想做总结或做记录。我的微信是 lijinma,希望和你交朋友。 以下是我的公众账号,会分享我的学习和成长。
本帖由 Summer 于 7年前 加精
lijinma
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 10
Summer

每一个操作放一个。。。又是一份为了写测试而写出来的代码。

7年前 评论
lijinma

@Summer 没办法 0.0 测试跑不通老板不让下班。。

7年前 评论

@lijinma 我们跑测试会在一个测试的 mysql 数据库操作。测试数据库定期大家全部更新,里面有一些准备好的数据,测试数据必须回滚。而开发也会在另外一个数据库。

7年前 评论
lijinma

@zhuzhichao 恩,我之前写了一篇文章,我们用 mysql 跑测试太慢了,我们只好又用户 SQLite Memory 的方式。

7年前 评论

file

官方建议上好像又写,是这个原因吗

话说。。。确实应该用 sqlite 在内存中跑测试,不过遇到多个 connection 你是怎么处理的,sqlite 可以优雅的解决吗

7年前 评论

@RryLee 装了dbal之后还是一样要把操作拆分了写 感觉特别不友好啊。。。

6年前 评论

简直神坑这个。。 所有的测试用例都error。。。 真的是。。。

6年前 评论
lijinma

@tradzero 哈哈哈哈

6年前 评论

@lijinma 不是,使用 sqlite 的 memory 的时候,怎么创建多个链接

6年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!