Drupal 8升级至9:Drush篡改数据库命名空间致类找不到错误
问题场景
我正在用Composer和Drush完成Drupal 8到Drupal 9的升级,处于数据库更新阶段。执行命令:
vendor/bin/drush updatedb:status
出现错误:
Error: Class 'Drupal\mysql\Driver\Database\mysql\Connection' not found
我的settings.php里数据库命名空间配置为'Drupal\Core\Database\Driver\mysql',但错误信息里的命名空间被额外插入了一段mysql,变成了Drupal\mysql\Driver\Database\mysql\Connection。即使注释掉settings.php中的命名空间配置,错误依然存在。如果故意把命名空间改成'Drupdddddal\Core\Database\Driver\mysql',错误就变成:
Class 'Drupdddddal\Core\Database\Driver\mysql\Connection' not found
这说明Drush确实在解析settings.php,但不清楚为什么会篡改命名空间,也不知道如何解决。
原因分析
这是Drupal 9数据库驱动结构变化导致的:Drupal 8中MySQL驱动是核心自带的,而Drupal 9将其移到了独立的drupal/mysql模块。如果项目未正确安装该模块,或者升级过程中驱动命名空间的解析逻辑出现过渡问题,就会触发这个错误。
解决步骤
1. 安装Drupal 9所需的MySQL驱动模块
执行Composer命令安装drupal/mysql:
composer require drupal/mysql
这是Drupal 9及以上版本必须的MySQL数据库驱动,升级后需要单独安装。
2. 修正settings.php中的数据库配置
将数据库连接数组里的namespace配置修改为'Drupal\mysql\Driver\Database\mysql',或者直接删除该配置项——Drupal 9会自动使用正确的默认命名空间。
3. 清除缓存并重新执行命令
先清除Drush和Drupal的缓存:
vendor/bin/drush cache:rebuild
再重新运行数据库更新状态命令:
vendor/bin/drush updatedb:status
额外排查点
如果以上步骤无效,检查Composer依赖是否正确:
- 执行
composer show drupal/core确认Drupal核心版本为9.x; - 检查
composer.json是否存在冲突依赖,比如旧的数据库驱动相关包,执行composer update将所有依赖更新到兼容版本。
完整堆栈信息
Error: Class 'Drupal\mysql\Driver\Database\mysql\Connection' not found in /home/XXXXXX/YYYYYYY/vendor/drupal/core/lib/Drupal/Core/Database/Database.php on line 413 #0 /home/XXXXXX/YYYYYYY/vendor/drupal/core/lib/Drupal/Core/Database/Database.php(189): Drupal\Core\Database\Database::openConnection('default', 'default') #1 /home/XXXXXX/YYYYYYY/vendor/drush/drush/src/Boot/DrupalBoot8.php(194): Drupal\Core\Database\Database::getConnection() #2 /home/XXXXXX/YYYYYYY/vendor/drush/drush/src/Boot/BootstrapManager.php(352): Drush\Boot\DrupalBoot8->bootstrapDrupalDatabaseValidate(Object(Drush\Boot\BootstrapManager)) #3 /home/XXXXXX/YYYYYYY/vendor/drush/drush/src/Boot/BootstrapManager.php(429): Drush\Boot\BootstrapManager->bootstrapValidate(4) #4 /home/XXXXXX/YYYYYYY/vendor/drush/drush/src/Boot/BootstrapManager.php(384): Drush\Boot\BootstrapManager->bootstrapToPhaseIndex(5, Object(Consolidation\AnnotatedCommand\AnnotationData)) #5 /home/XXXXXX/YYYYYYY/vendor/drush/drush/src/Boot/BootstrapHook.php(32): Drush\Boot\BootstrapManager->bootstrapToPhase('full', Object(Consolidation\AnnotatedCommand\AnnotationData)) #6 /home/XXXXXX/YYYYYYY/vendor/consolidation/annotated-command/src/Hooks/Dispatchers/InitializeHookDispatcher.php(44): Drush\Boot\BootstrapHook->initialize(Object(Symfony\Component\Console\Input\ArgvInput), Object(Consolidation\AnnotatedCommand\AnnotationData)) #7 /home/XXXXXX/YYYYYYY/vendor/consolidation/annotated-command/src/Hooks/Dispatchers/InitializeHookDispatcher.php(36): Consolidation\AnnotatedCommand\Hooks\Dispatchers\InitializeHookDispatcher->doInitializeHook(Object(Drush\Boot\BootstrapHook), Object(Symfony\Component\Console\Input\ArgvInput), Object(Consolidation\AnnotatedCommand\AnnotationData)) #8 /home/XXXXXX/YYYYYYY/vendor/consolidation/annotated-command/src/Hooks/Dispatchers/InitializeHookDispatcher.php(29): Consolidation\AnnotatedCommand\Hooks\Dispatchers\InitializeHookDispatcher->callInitializeHook(Object(Drush\Boot\BootstrapHook), Object(Symfony\Component\Console\Input\ArgvInput), Object(Consolidation\AnnotatedCommand\AnnotationData)) #9 /home/XXXXXX/YYYYYYY/vendor/consolidation/annotated-command/src/CommandProcessor.php(145): Consolidation\AnnotatedCommand\Hooks\Dispatchers\InitializeHookDispatcher->initialize(Object(Symfony\Component\Console\Input\ArgvInput), Object(Consolidation\AnnotatedCommand\AnnotationData)) #10 /home/XXXXXX/YYYYYYY/vendor/consolidation/annotated-command/src/AnnotatedCommand.php(335): Consolidation\AnnotatedCommand\CommandProcessor->initializeHook(Object(Symfony\Component\Console\Input\ArgvInput), Array, Object(Consolidation\AnnotatedCommand\AnnotationData)) #11 /home/XXXXXX/YYYYYYY/vendor/symfony/console/Command/Command.php(221): Consolidation\AnnotatedCommand\AnnotatedCommand->initialize(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput)) #12 /home/XXXXXX/YYYYYYY/vendor/symfony/console/Application.php(1027): Symfony\Component\Console\Command\Command->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput)) #13 /home/XXXXXX/YYYYYYY/vendor/symfony/console/Application.php(273): Symfony\Component\Console\Application->doRunCommand(Object(Consolidation\AnnotatedCommand\AnnotatedCommand), Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput)) #14 /home/XXXXXX/YYYYYYY/vendor/symfony/console/Application.php(149): Symfony\Component\Console\Application->doRun(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput)) #15 /home/XXXXXX/YYYYYYY/vendor/drush/drush/src/Runtime/Runtime.php(124): Symfony\Component\Console\Application->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput)) #16 /home/XXXXXX/YYYYYYY/vendor/drush/drush/src/Runtime/Runtime.php(51): Drush\Runtime\Runtime->doRun(Array, Object(Symfony\Component\Console\Output\ConsoleOutput)) #17 /home/XXXXXX/YYYYYYY/vendor/drush/drush/drush.php(72): Drush\Runtime\Runtime->run(Array) #18 /home/XXXXXX/YYYYYYY/vendor/drush/drush/drush(3): require('/home/XXXXXX/...') #19 /home/XXXXXX/YYYYYYY/vendor/bin/drush(115): include('/home/XXXXXX/...') #20 {main}
内容的提问来源于stack exchange,提问作者Paul P

