如何删除属于模块内容类型的字段的痕迹?

Tyl*_*ler 6 content-type drupal drupal-7 drupal-modules

我正在尝试学习如何从我的模块中以编程方式创建自定义内容类型.

但是,卸载并重新安装我的模块后,我收到一条错误消息,指出我尝试创建的一个或多个字段无法创建,因为它们已经存在.

所以我破解了我的数据库,删除了内容类型和所有属于它的表.

相同的结果 - 字段已存在.

接下来,我访问了Drupal API网站,寻找删除字段和字段实例的方法,并且遇到了

field_delete_field()
Run Code Online (Sandbox Code Playgroud)

field_delete_instance()
Run Code Online (Sandbox Code Playgroud)

我创建了一个php页面来尝试删除我创建的字段,只是为了得到一个错误,指出我试图删除的表不存在.

所以我有点卡住 - 我不能创建字段,因为它们已经存在,我不能删除它们,因为它们不存在!

顺便说一句,我在为我的模块建模的代码是在Drupal 示例模块的"node_example"部分中找到的代码.

Cli*_*ive 4

哎哟,手动删除数据库表从来都不是一个好主意 - Drupal 没有那么宽容:)

只是为了解决安装/启用挂钩中的代码,将字段创建包装在:

if (!field_info_field('field_name')) {
  field_create_field(...
}
Run Code Online (Sandbox Code Playgroud)

这将阻止问题再次发生。或者,如果您不想这样做,请确保在卸载/禁用挂钩中删除该字段。显然,该方法可能会导致数据丢失。

要解决当前问题,请遵循以下流程:

  • 完全卸载(不仅仅是禁用)您的自定义模块。如果它处于不一致状态,只需删除表中其行即可system
  • field_config从和表中删除该字段的所有痕迹field_config_instance
  • 手动截断所有缓存表(任何以 开头的表cache_)。
  • 不是绝对必要的,但要清除所有残留的内容:

    $nids = db_query('SELECT nid FROM {node} WHERE type = :type', array(':type' => 'type'))->fetchCol();
    node_delete_multiple($nids);
    
    Run Code Online (Sandbox Code Playgroud)

应该可以做到这一点。

每当您通过 UI 或以编程方式删除字段时,您都需要运行 cron 或调用field_purge_batch()“硬”删除字段,因为它们仅在第一个实例中被标记为删除。