Laravel表*没有名为*的列。

18

我的单元测试最近开始失败了。我收到了这个错误:

PDOException: SQLSTATE[HY000]: 
General error: 1 table loan_details has no column named start_month

发生问题的那一行,我有这段代码:

$loan = LoanDetails::create(['loan_percentage' => .8,
        'loan_product_id' => 1,
        'interest_rate' => .5,
        'start_month' => 0,
        'term' => 120,
        'fixed_finance_fee' => 0,
        'variable_finance_Fee' => 0,
        'valid_from' => '2015-01-01'
    ]);

如果我将"start_month"这一行注释掉,那么它就可以按照逻辑正常工作。

在我的单元测试设置中,我运行了所有的迁移(大约80个)。

我有一个迁移文件看起来像这样:

Schema::table('loan_details', function(Blueprint $table){
     $table->integer('start_month')->unsigned()->after('interest_only')->default(0);
     $table->decimal('balloon_percent',4,3)->after('term')->nullable();
     $table->integer('balloon_month')->after('balloon_percent')->nullable();
     $table->dropColumn('ordinal_rank');
});

所以,我想知道是否所有的迁移都没有运行,于是我运行了这段代码:

$rows = DB::table('migrations')->get();
print_r($rows);

这列出了所有迁移都已完成。我的测试中使用了一个内存SQLite数据库。

我想知道这些迁移是否是异步运行的,它们在我的代码运行时是否全部完成?或者这些迁移是否在某个地方悄悄失败了?

我已经做了几个小时了,不知道发生了什么。

*更新:我有一个在上述迁移之后运行的迁移,并确认后续迁移成功了。所以只有这一个迁移以某种方式悄悄失败了。


你看到在迁移列表中运行的迁移中添加列的操作了吗? - jedrzej.kurylo
是的,我列出了所有的内容,包括我期望的那一个。 - ajon
你看到数据库中的那一列了吗?如果迁移运行时出现错误,即使未完成,它也可能保存在迁移表中。 - jedrzej.kurylo
我假设它不在数据库中。我不知道如何检查内存中的SQLite数据库。 - ajon
如果这是最后一个迁移,你可以尝试用"php artisan migrate:rollback"回滚它,然后再运行"php artisan migrate"重新执行它。 - jedrzej.kurylo
原始的迁移已经在生产环境中运行。 - ajon
2个回答

48

我找到了问题所在。这是因为SQLite有一个荒谬的限制,即不能在一个表调用中使用多个添加列语句,如此处所示。

当我将迁移分开写如下时,它可以工作:

Schema::table('loan_details', function(Blueprint $table){
    $table->integer('start_month')->unsigned()->after('interest_only')->default(0);
});
Schema::table('loan_details', function(Blueprint $table){
    $table->decimal('balloon_percent',4,3)->after('term')->nullable();
});
Schema::table('loan_details', function(Blueprint $table){
    $table->integer('balloon_month')->after('balloon_percent')->nullable();
});
Schema::table('loan_details', function(Blueprint $table){
    $table->dropColumn('ordinal_rank');
});

1
谢谢你的回答。这对我帮助很大。非常令人失望的是,您无法使用 $table->morphs('taggable');,因为这会创建两个列和一个索引,在使用 sqlite 进行单元测试时会出现问题。 - Hendrik
谢谢这个。这真的对我很有帮助并且有效。 - Jur P
1
我可以编写测试来检查模式是否正确,但这似乎有些荒谬。$this->assertTrue(Schema::hasColumn('users', 'firstName'), 'Users table does not have a firstName column.'); $this->assertTrue(Schema::hasColumn('users', 'lastName'), 'Users table does not have a lastName column.');我可以通过从测试中执行以下操作来查看sqlite模式。 dd(DB::select("SELECT name, sql FROM sqlite_master WHERE type='table' ORDER BY name;")); - Liam Mitchell

2

查看SQLite数据库记录请点击这里

还有许多其他有用的内置dot命令--请参阅http://www.sqlite.org/sqlite.html文档,特别是sqlite3的特殊命令部分。

同时,请检查数据库模式。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接