以编程方式在数据库中更改术语的vid列是否可以接受?


8

我需要通过保留所有术语的所有数据将它们从一个词汇移到另一个词汇:翻译,别名和节点引用。

vid直接在数据库中更改其列值是否可以接受?术语没有需要处理的层次关系。

Answers:


11

数据库

只需通过Drupal或从外部进行SQL查询,就可以在Drupal中做很多事情。通常,您永远都不想采用这种方法。在某些情况下,它可以正常工作,但是在大多数情况下,没有理由这样做。

API

Drupal具有丰富的API,Drupal 6、7和8确实如此,因为它们一直是Drupal的关键功能。在您的concreate示例中,您可以使用taxonomy_term_loadtaxonomy_term_save促进术语的更新。这样,您可以编辑任何数据部分,包括vid。仅仅因为您使用API​​来做,被禁止的事情不会自动起作用,但是事情进展的机会得到了极大的提高。

在此具体示例中,API不会执行任何必需的操作。它在该术语上设置了一些内部数据,并通过调用钩子字母模块知道已更新。

您应该注意,如果要更改的术语是层次结构的一部分,则事情可能会中断。如果不允许该字段引用新词汇表中的术语,则对于引用该术语的节点来说,事情也可能会中断。

移民

数据迁移是防弹解决方案,除非您拥有庞大的数据集,否则可以轻松开发和执行它。这个想法是创建一个新术语并迁移您想要迁移的内容,然后删除旧术语。作为更新挂钩,示例代码如下所示:

/**
 * Put in modules .install file, replace xxxx with 7000 or higher
 */
function MODULE_NAME_update_XXXX(&$sandbox) {
  $term = taxonomy_term_load(CONSTANT_WITH_TID);
  $new_term = clone $term;
  unset($new_term->tid);
  unset($new_term->tid);
  $new_term->vid = CONSTANT_WITH_VID;
  taxonomy_term_save($term);
  // Find all nodes we want to update and update them.
  // If there is a lot of nodes, can use $sandbox to make this a batch job.
  $query = new EntityFieldQuery();
  $query->entityCondition('entity_type', 'node')
    ->fieldCondition('field_which_is_term_reference', 'tid', $term->tid);
  $result = $query->execute();
  foreach (node_load_multiple(array_keys($result['node'])) as $node) {
    $node->field_which_is_term_reference[LANGUAGE_NONE][0]['tid'] = $term->tid;
    node_save($node);
  }
  // Migration all done - delete the old term.
  taxonomy_term_delete($term->tid);
}

请注意,以上代码是纯示例代码,由衷地编写。可能存在语法错误或其他错误,并且会做出很多假设。这仅是为了说明一个想法,并表明迁移可能并不重要。


4

这是不可取的使用Drupal工作时做数据库的直接变化。但是,是的,如果我们知道所有它可以影响并相应地做必要的修改,它是确定做数据库中直接修改。因为在这种情况下,这不可能通过UI进行。注意:如果您有与Term相关联的节点,则也必须手动处理它。

查看此链接,该链接说明了我们如何在Drupal 7中更改术语词汇表:使用数据库在Drupal 7中更改分类术语的词汇表


我看到的唯一问题是-如果万一某个术语附加了带有某些值的字段,而您更改了其vid,则存储在该字段中的数据将丢失。
Ashish Deynap '16

是的,这就是为什么我也提到,如果连接了任何节点那么也需要处理这些节点
Yogesh

但是,vid也将任何数据附加到术语上吗?不仅是按tid键?
Molfar '16

不,任何附加在term上的数据都与tid有关。vid仅用于引用词汇表ID,仅用于引用。
Yogesh

4

我不建议您以在问题中描述的方式更改该术语。相反,我将使用一种替代方法来实现类似的结果(按指定的顺序),下面将对此进行详细说明。

步骤1-在以后的节点更新中开始使用新术语

创建一个新的分类术语字段,以便“从现在开始”任何将来的节点更新(或正在创建的新节点)都将使用该新字段。我假设这些术语用于节点(如果您将其用于某些其他实体类型,例如用户等),则相同的方法也可以用于那些实体。

使用“ 规则”模块创建如下规则:

  • 规则事件:before saving content
  • 规则条件:
    • entity has field,其中field =旧字段。
    • AND NOT(entity has field,其中field =新字段)。
  • 规则操作:set Drupal message,其中包含一些说明,必须将旧字段清空,而新字段应包含适当的值。

第2步-使用规则加快流程

显然,如果必须手动完成一次,则步骤1中的方法将花费“一些”时间,每次需要1个节点。但是,使用Views(构建要更新的类似节点的列表)和VBO(大规模更新此类列表),您可能(应该!)可以大大加快此过程。

特别是如果您要使用“规则”为此类VBO视图创建自定义批量操作,请参见“ 如何使用规则为VBO视图创建自定义批量操作? ”中的解释。这是一个规则组件的原型,它应有助于实现这种自定义批量操作(以“规则导出”格式):

{ "rules_replace_a_term_field_by_another_term_field" : {
    "LABEL" : "Replace a term field by another term field",
    "PLUGIN" : "rule",
    "OWNER" : "rules",
    "REQUIRES" : [ "rules" ],
    "USES VARIABLES" : { "node" : { "label" : "Node", "type" : "node" } },
    "IF" : [
      { "entity_has_field" : { "entity" : [ "node" ], "field" : "field_sample_tags" } },
      { "entity_has_field" : { "entity" : [ "node" ], "field" : "field_demo_tags" } },
      { "data_is" : { "data" : [ "node:field-demo-tags" ], "value" : "1" } }
    ],
    "DO" : [
      { "data_set" : { "data" : [ "node:field-sample-tags" ], "value" : "31" } },
      { "drupal_message" : { "message" : "Term updated in node with id = [node:nid]" } }
    ]
  }
}

一些更多细节来解释上述原型:

  • 它使用节点作为参数。
  • 这些是规则条件:

    • 检查实体(=节点)是否具有field field_sample_tags
    • 检查实体(=节点)是否具有field field_demo_tags
    • 检查该字段的值是否field_demo_tags对应于我们要替换的术语(在此示例中,该术语具有id = 1)。请注意,如果不满足此条件,则不会执行任何规则操作。
  • 这些是规则操作:

    • 将字段的值设置为field_sample_tags等于带有术语id = 31的术语(这是新创建的词汇表中与要替换的词汇表中的术语匹配的术语)。
    • 在类似的网站上显示一条消息Term updated in node with id = 72,而是72更新节点的节点ID。

如果需要,请调整以上原型中字段名称的机器名称以及使用的术语ID。然后将其导入您自己的站点(使用Rules UI),并使用导入的Rules Component右侧的“ execute”链接进行质量检查(并在切换到“直接输入后输入一些节点ID进行测试”模式”以能够指定节点ID)。如果在测试过程中没有收到这样的Term updated in node ...消息,那一定是因为您选择的节点未使用规则条件中指定的术语值。

第3步-使用VBO作为画龙点睛

在完成对第2步中的“规则”组件的质量检查测试之后,创建要处理的节点的VBO视图,在其中,您可以参考上面的“规则”原型(或为满足您的需要而对其进行的变形)。

这种方法的好处

使用这种方法,您可以最大程度地降低引入数据不一致的风险(与直接更新数据库相比),并且只需零个自定义代码(您只能使用Views UI和Rules UI)。


您假定已经安装了视图,VBO和规则,否则需要为该解决方案安装3个模块。另外,您需要实现的配置“代码”与更新挂钩中所要做的一样复杂。我的观点是,使用规则和视图并不像听起来那么简单。还值得记住的是,尽管您几乎可以使用“视图和规则”进行任何操作,但这并不总是一个好主意。
googletorp

1
确实可以:要使用“视图”,“规则”或VBO,必须安装该模块(已启用+)。但是从大约990K D7网站中,大约有81万个站点还具有Views,占了80%以上。对于没有理由使用“规则”或VBO的网站:这些模块仅需要进行这种转换(完成后可以根据需要将其删除)。关于简单性:IMO是一个经验问题。这种方法的优势在于,它仅需要网站建设技能(经验丰富的PHP开发人员可能不可用/负担不起)。
Pierre.Vriens

2

我知道您是通过编程方式说出来的,但是如果您想使用模块,可以使用Taxonomy Manager

该模块提供了用于管理分类法的强大接口。词汇将显示在动态树视图中,在其中可以扩展父项以列出其嵌套的子项,也可以将其折叠。

分类管理器具有以下操作和关键功能:

  • 动态树视图
  • 批量删除
  • 大量增加新术语
  • 在术语合并中移动术语(使用7.x中的“术语合并”模块)
  • 上下箭头可快速改变重量(并节省AJAX)
  • AJAX支持的术语编辑表单
  • 简单的搜索界面
  • CSV导出条款
  • i18n支持多语言词汇(按语言术语)
  • Double Tree界面,用于在层次结构中移动术语,添加新的翻译并在不同词汇之间切换术语
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.