You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Drupal 11配置同步遇数据库漂移,如何自动化实现数据库迁移?

解决Drupal 11 Paragraphs模块配置导入时实体表缺失的自动化方案

问题根源

Drupal的配置系统与实体数据库架构是解耦的:配置文件仅存储段落类型等实体的定义,而对应的数据库表由实体系统的安装/更新逻辑管理。全新部署时,若先执行配置导入,此时Paragraphs模块虽已启用,但自定义段落类型对应的实体架构尚未同步到数据库,就会触发表不存在的错误。

自动化解决方案

1. 优化部署脚本命令顺序

将实体架构更新整合到部署流程中,无需手动操作。在部署脚本中按以下顺序执行命令:

# 确保Paragraphs模块已启用(首次部署时需要)
drush pm:enable paragraphs -y

# 自动同步实体架构与当前定义,无需交互确认
drush entity:update --no-interactive -y

# 执行配置导入
drush config:import -y

即使没有待更新的架构,drush entity:update也不会破坏现有数据,可安全加入部署流程。

2. 自定义模块自动触发架构更新

若需要更贴合Drupal生态的自动化方式,可编写自定义模块,监听配置导入事件,自动执行实体架构同步:

步骤1:创建自定义模块(例:deploy_auto_entity_update)

在modules/custom/deploy_auto_entity_update目录下创建以下文件:

deploy_auto_entity_update.info.yml
name: 'Deploy Auto Entity Update'
type: module
description: 'Automatically updates entity schemas after config import.'
core_version_requirement: ^11
package: 'Custom'
deploy_auto_entity_update.services.yml
services:
  deploy_auto_entity_update.subscriber:
    class: Drupal\deploy_auto_entity_update\EventSubscriber\DeployAutoEntityUpdateSubscriber
    arguments: ['@entity_type.manager', '@entity.last_installed_schema.repository']
    tags:
      - { name: event_subscriber }
事件订阅者类(src/EventSubscriber/DeployAutoEntityUpdateSubscriber.php)
<?php

namespace Drupal\deploy_auto_entity_update\EventSubscriber;

use Drupal\Core\Entity\EntityLastInstalledSchemaRepositoryInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Utility\UpdateException;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Drupal\Core\Config\ConfigImporterEvent;
use Drupal\Core\Config\ConfigImporterEvents;

class DeployAutoEntityUpdateSubscriber implements EventSubscriberInterface {

  protected $entityTypeManager;
  protected $lastInstalledSchemaRepository;

  public function __construct(EntityTypeManagerInterface $entity_type_manager, EntityLastInstalledSchemaRepositoryInterface $last_installed_schema_repository) {
    $this->entityTypeManager = $entity_type_manager;
    $this->lastInstalledSchemaRepository = $last_installed_schema_repository;
  }

  public static function getSubscribedEvents() {
    $events[ConfigImporterEvents::AFTER_IMPORT] = ['onAfterConfigImport'];
    return $events;
  }

  public function onAfterConfigImport(ConfigImporterEvent $event) {
    // 遍历所有内容实体类型,检查并更新架构
    foreach ($this->entityTypeManager->getDefinitions() as $entity_type_id => $entity_type) {
      if (!$entity_type->isSubclassOf('\Drupal\Core\Entity\ContentEntityTypeInterface')) {
        continue;
      }

      $original_schema = $this->lastInstalledSchemaRepository->getLastInstalledFieldStorageDefinitions($entity_type_id);
      $current_schema = $this->entityTypeManager->getStorage($entity_type_id)->getFieldStorageDefinitions();

      if ($original_schema !== $current_schema) {
        try {
          $this->entityTypeManager->getStorage($entity_type_id)->updateSchema();
          \Drupal::logger('deploy_auto_entity_update')->notice('Updated schema for entity type: @type', ['@type' => $entity_type_id]);
        }
        catch (UpdateException $e) {
          \Drupal::logger('deploy_auto_entity_update')->error('Failed to update schema for @type: @message', [
            '@type' => $entity_type_id,
            '@message' => $e->getMessage(),
          ]);
        }
      }
    }
  }
}

步骤2:启用自定义模块

在部署脚本中加入drush pm:enable deploy_auto_entity_update -y,之后每次配置导入完成后,模块会自动检查并更新所有实体的数据库架构。

3. 对比传统数据库迁移工具

Drupal的实体架构管理逻辑与传统迁移工具(如Flyway、Liquibase)不同,它依赖实体定义与数据库的自动同步。上述方案本质是将drush entity:update的手动操作自动化,贴合Drupal的原生工作流,无需额外维护独立的迁移脚本。

内容的提问来源于stack exchange,提问作者importTurtle

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 08:28:17