Laravel添加FULLTEXT索引后运行PHPUnit报SQL语法错误求助
解决Laravel迁移添加FULLTEXT索引后PHPUnit报错的问题
我之前也碰到过一模一样的问题,折腾了好一会儿才找到根源,主要是这几个方面的问题,咱们一个个来解决:
1. 测试环境数据库不支持FULLTEXT索引
很多人跑PHPUnit测试的时候默认用的是SQLite,但SQLite对FULLTEXT索引的支持非常有限——只有创建FTS虚拟表或者特定配置的普通表才能用,咱们常规的products表根本加不了FULLTEXT索引,这就会直接抛出语法错误。
解决方案:
要么把测试环境的数据库换成和生产一致的MySQL,要么在迁移里判断数据库类型,只在支持的数据库上执行索引操作:
use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Schema; public function up() { // 只在MySQL环境下添加FULLTEXT索引 if (Schema::getConnection()->getDriverName() === 'mysql') { DB::statement('ALTER TABLE products ADD FULLTEXT `fulltext_index`(`name`)'); } } public function down() { if (Schema::getConnection()->getDriverName() === 'mysql') { // 注意要指定表名,否则数据库不知道要删哪个索引 DB::statement('DROP INDEX `fulltext_index` ON products'); } }
2. SQL语句的语法错误
你原来的迁移里有两个语法问题:
down方法里的DROP INDEX fulltext_index缺少表名,MySQL必须明确知道要删除哪个表上的索引;- 索引名和字段名最好用反引号包裹,避免和MySQL关键字冲突(虽然
name和fulltext_index不是关键字,但养成习惯更稳妥)。
修正后的语句就是上面代码里的样子,亲测有效。
3. 确保表引擎支持FULLTEXT
FULLTEXT索引只支持MyISAM或者InnoDB(MySQL 5.6及以上版本),如果你的products表用的是其他引擎(比如MEMORY),也会报错。可以先检查表的引擎,或者在迁移里强制设置:
// 如果是新建表,创建时指定引擎 Schema::create('products', function (Blueprint $table) { $table->engine = 'InnoDB'; // ...其他字段定义 }); // 如果是已存在的表,修改引擎 DB::statement('ALTER TABLE products ENGINE = InnoDB');
按上面的步骤调整后,再跑PHPUnit测试应该就不会报错了。
内容的提问来源于stack exchange,提问作者Harry Andriyan
相关产品推荐
相关产品推荐

