Drupal 7中如何将一种内容类型的字段与数据迁移至另一种
别发愁,这事儿在Drupal 7里绝对能解决!我给你两种靠谱的路子,模块法(推荐,安全省心)和SQL法(适合有数据库经验的,谨慎操作):
这种方法不用碰数据库,靠成熟模块就能搞定,分两步:复制字段配置 + 迁移内容数据。
1. 把ContentA的字段复制到ContentB
推荐用Field Tools模块,它自带「克隆字段实例」的功能:
- 安装并启用Field Tools模块
- 进入「结构 > 内容类型 > ContentA > 管理字段」页面,重点处理Summary字段(Title是默认字段,ContentB大概率已经有了)
- 点击字段右侧的「克隆」选项,在弹出界面里选择目标内容类型为ContentB,确认后就能把字段配置完整复制过去
如果Summary是body字段的内置摘要,那只要给ContentB的body字段开启摘要功能就行,不用额外克隆。
2. 迁移ContentA的所有内容到ContentB
用Feeds模块批量导入最方便:
- 安装并启用Feeds和Feeds UI模块
- 进入「结构 > Feeds导入器」,点击「添加导入器」,给导入器起个直观的名字(比如「ContentA转ContentB」)
- 配置数据源:选择「内容」作为源类型,再选中ContentA作为要导入的内容类型
- 配置处理器:选择「节点」,目标内容类型选ContentB,按需勾选「更新现有内容」避免重复
- 配置字段映射:把ContentA的Title映射到ContentB的Title,Summary映射到ContentB的Summary,作者、发布状态等必要字段也按需对应
- 保存配置后点击「导入」,选择「从ContentA获取内容」,就能批量把所有ContentA的内容转成ContentB的了
如果模块法搞不定,或者你熟悉数据库操作,可以直接动数据库,但一定要先在测试环境试,并且备份好所有数据!
前提准备
先手动给ContentB创建好和ContentA完全一致的字段:字段机器名、类型、配置都要一模一样(比如ContentA的Summary是field_summary,ContentB也要创建相同机器名的同类型字段)
步骤1:复制节点基础数据
把ContentA的节点数据复制到node表,注意把内容类型改成ContentB的机器名(假设ContentA的机器名是content_a,ContentB是content_b):
INSERT INTO node (type, title, uid, created, changed, status, promote, sticky, language) SELECT 'content_b', title, uid, created, changed, status, promote, sticky, language FROM node WHERE type = 'content_a';
步骤2:复制节点修订版本数据
节点的修订版存在node_revision表,同样复制:
-- 先获取刚插入的新节点ID列表 CREATE TEMPORARY TABLE temp_nids AS SELECT nid FROM node WHERE type = 'content_b' AND created IN (SELECT created FROM node WHERE type = 'content_a'); -- 复制修订数据,关联新的nid INSERT INTO node_revision (nid, vid, uid, title, created, changed, log) SELECT t.nid, (SELECT MAX(vid) + 1 FROM node_revision) + ROW_NUMBER() OVER (ORDER BY nr.vid), nr.uid, nr.title, nr.created, nr.changed, nr.log FROM node_revision nr JOIN node n ON nr.nid = n.nid JOIN temp_nids t ON n.created = (SELECT created FROM node WHERE nid = t.nid) WHERE n.type = 'content_a'; DROP TEMPORARY TABLE temp_nids;
步骤3:复制字段数据
如果Summary是自定义字段(比如field_summary),要复制field_data_field_summary和field_revision_field_summary两张表的数据:
-- 复制字段数据(field_data表) INSERT INTO field_data_field_summary (entity_type, entity_id, revision_id, bundle, delta, language, field_summary_value) SELECT 'node', t.nid, (SELECT vid FROM node_revision WHERE nid = t.nid ORDER BY vid DESC LIMIT 1), 'content_b', delta, language, field_summary_value FROM field_data_field_summary f JOIN node n ON f.entity_id = n.nid JOIN temp_nids t ON n.created = (SELECT created FROM node WHERE nid = t.nid) WHERE n.type = 'content_a'; -- 复制字段修订数据(field_revision表) INSERT INTO field_revision_field_summary (entity_type, entity_id, revision_id, bundle, delta, language, field_summary_value) SELECT 'node', t.nid, nr.vid, 'content_b', delta, language, field_summary_value FROM field_revision_field_summary f JOIN node_revision nr ON f.revision_id = nr.vid JOIN node n ON nr.nid = n.nid JOIN temp_nids t ON n.created = (SELECT created FROM node WHERE nid = t.nid) WHERE n.type = 'content_a';
如果Summary是body字段的内置摘要,就把上面的field_summary换成body,对应字段列改成body_summary即可。
最后一步:清理Drupal缓存
不管用哪种方法,操作完后一定要清空Drupal的缓存(进入「配置 > 性能 > 清空所有缓存」),不然新的内容类型和数据可能不会立刻显示。
内容的提问来源于stack exchange,提问作者Kumar

