0

I am removing a field that was added using hook_base_field_info:

/**
 * Implements hook_entity_base_field_info().
 */
function MYMODULE_entity_base_field_info(EntityTypeInterface $entity_type) {
  $fields = array();


  if ($entity_type->id() === 'node') {
    $field_definitions['some_field'] = \Drupal\Core\Field\BaseFieldDefinition::create('datetime')
      ->setLabel(t('some  field'))
      ->setDescription(t('description'))
      ->setRevisionable(TRUE)
      ->setTranslatable(TRUE)
      ->setSetting('datetime_type', 'date')
      ->setDisplayOptions('view', [
        'label' => 'inline',
        'type' => 'datetime_default',
        'weight' => 1,
        'settings' => [
          'format_type' => 'html_date',
          'timezone_override' => '',
        ],
      ])
      ->setDisplayConfigurable('view', TRUE)
      ->setDisplayOptions('form', array(
        'type' => 'datetime_default',
        'weight' => 10,
      ))
      ->setDisplayConfigurable('form', TRUE);

    return $fields;
  }
}

I removed the code and ran drush entup I get the following error repeatedly:

drush entup -y The following updates are pending:

node entity type : Some Field field needs to be uninstalled.

// Do you wish to run all pending updates?: yes.

 [error]  SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '22906-42845-1-0-de' for key 'PRIMARY': INSERT INTO {field_deleted_revision_01c8f04bcd} (bundle, entity_id, revision_id, langcode, some_field_value, deleted, delta) SELECT base_table.type AS bundle, entity_table.nid AS entity_id, entity_table.vid AS revision_id, entity_table.langcode AS langcode, entity_table.compliance_approval_date AS some_field_value, :deleted AS deleted, :delta AS delta
FROM 
{node_field_revision} entity_table
INNER JOIN {node_field_data} base_table ON entity_table.nid = base_table.nid
WHERE entity_table.some_field IS NOT NULL FOR UPDATE; Array
(
    [:deleted] => 1
    [:delta] => 0
)

Any idea why this is caused and how one might go about fixing it?

  • Looks like it may have crashed half way through one entup and then you ran it again? Possibly it managed to insert some of the records before failing, but when you run it again it expects the table to be empty, hence the duplicate entries. It might not be that of course, it's just a guess. I'd be tempted to backup the DB, truncate the field_deleted_revision_01c8f04bcd table, and try again – Clive Sep 12 '18 at 19:25
1

drush entup is the wrong tool (I hope you have a database backup from before you've executed this command). After uninstalling the module containing the node base field, wait until cron has gradually purged the existing field data, see the change record Base fields with existing data can now be uninstalled.

  • I am not uninstalling the module but just removing the field. Would that make the process any different? and I am working locally so have db backups. The problem with waiting for the cron to purge is that all this need to happen on deployment. Is there an alternative approach? – awm Sep 12 '18 at 20:12
  • Then you need an update hook, but I've never seen an example how to delete a base field. So for now uninstalling the module seems to be the official way to uninstall a base field. For deploying you should never use drush entup. Purging of the field data by cron is not time sensitive, as long as you don't run out of database space. But you can of course run cron more often or increase the batch size, see drupal.stackexchange.com/questions/253055/… – 4k4 Sep 12 '18 at 20:28
  • I was able to do it in an update hook using $entity_definition_update_manager->uninstallFieldStorageDefinition . I followed examples in core. However, my my configuration is cluttered with that field name such as core.base_field_override.node.article.my_field and if I manually delete the file, importing configuration starts throwing errors. Starting to wonder if it's impossible to remove actually. – awm Sep 13 '18 at 17:22
  • If you override one value of a base field definition in a content type Drupal copies to entire field definition to config. Probably you have then dependencies in view and form modes as well. I wonder if uninstalling the module removes all of this. If yes, you could do this temporarily, to get a working configuration set. – 4k4 Sep 13 '18 at 18:22
  • I was able to manually update the configuration and delete the overrides after applying a patch. I posted my answer which I am not sure works for all but did the job for me as it appears so far. fingers crossed ... – awm Sep 13 '18 at 20:17
1

I was able to remove the base field without uninstalling the module after looking at some core examples. Note this need to be used carefully as it may have unintended consequences:

I first added a hook update:

/**
 * Remove my_field
 */
function my_module_update_8107() {
  $field_name = 'my_field';

  $tables_to_update = [
    'node_field_data',
    'node_field_revision'
  ];

  $database = Drupal::database();
  $entity_definition_update_manager = Drupal::entityDefinitionUpdateManager();

  // Ensure that the data from the  field is deleted
  // so that the field can safely be deleted.
  foreach ($tables_to_update as $table_to_update) {
    if ($database->schema()->fieldExists($table_to_update, $field_name)) {
      $database->update($table_to_update)
        ->fields([$field_name => NULL])
        ->execute();
    }
  }

  // Delete the storage definition if it was defined before.
  $storage_definition = $entity_definition_update_manager->getFieldStorageDefinition($field_name, 'node');
  if ($storage_definition) {
    $entity_definition_update_manager->uninstallFieldStorageDefinition($storage_definition);
  }
}

Then I removed the all the core.base_field_override.node.[TYPE].my_field yaml files. This caused the configuration import to fail with an error reported to d.o. I applied the patch at the link and configuration import now work correctly. And finally I removed the field settings from all the display yaml files.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.