0

When I visit /admin/reports/status, I am told that a few entities have fields that need to be updated or reinstalled. I created an update hook:

/**
 * Remove the result field from the analysis entity and reinstall
 */
function mymodule_update_8101(&$sandbox) {

  $entity_name = 'analysis';
  $old_field_name = 'result';
  $new_field_name = 'result';

  $field_definition = BaseFieldDefinition::create('decimal')
      ->setLabel(t('Results'))
      ->setDescription(t('Results.'))
      ->setSettings([
        'precision' => 12,
        'scale' => 4,
      ])
      ->setDisplayOptions('view', array(
        'label' => 'above',
        'type' => 'number_decimal',
        'weight' => -4,
      ))
      ->setDisplayOptions('form', array(
        'type'     => 'number',
        'weight'   => 5,
      ))
      ->setDisplayConfigurable('form', TRUE)
      ->setDisplayConfigurable('view', TRUE)
      ->setRequired(FALSE);
  mymodule_replace_field($entity_name, $old_field_name, $new_field_name, $field_definition);
}

/**
 * Replace a field in an entity.
 *
 */
function mymodule_replace_field($entity_name, $old_field_name, $new_field_name, $field_definition) {
  $definition_manager = \Drupal::entityDefinitionUpdateManager();
  $old_field_storage_definition = $definition_manager->getFieldStorageDefinition($old_field_name, $entity_name);
  $connection = \Drupal::database();

  if ($new_field_name !== $old_field_name) {
    $definition_manager->installFieldStorageDefinition($new_field_name, $entity_name, $entity_name, $field_definition);
    $connection->update($entity_name)
      ->expression($new_field_name, $old_field_name)
      ->execute();
    $definition_manager->uninstallFieldStorageDefinition($old_field_storage_definition);
  }
  else {
    $definition_manager->installFieldStorageDefinition('temp_column', $entity_name, $entity_name, $field_definition);
    $connection->update($entity_name)
      ->expression('temp_column', $old_field_name)
      ->execute();
    $definition_manager->uninstallFieldStorageDefinition($old_field_storage_definition);
    $definition_manager->installFieldStorageDefinition($new_field_name, $entity_name, $entity_name, $field_definition);
    $connection->update($entity_name)
      ->expression($new_field_name, 'temp_column')
      ->execute();
    $temp_field_storage_definition = $definition_manager->getFieldStorageDefinition('temp_column', $entity_name);
    $definition_manager->uninstallFieldStorageDefinition($temp_field_storage_definition);
  }
}

After running this hook, the error goes away until cron runs, then it returns. I was able to determine that the "needs to be updated" is triggered by SqlContentEntityStorageSchema::loadFieldSchemaData() returning an empty array after cron runs. If I run the update hook, the function returns an array with mostly correct information. After cron runs, it is empty. I am running D8 with SQL Server.

  • Have you applied the same code change (i.e. the new field definition) to the baseFieldDefinitions method of the entity type class? – Clive Mar 18 at 14:53
  • The field definition in the update hook above is copied verbatim from the Entity class file (mymodule/src/Entity/Analysis.php). – Kevin Nowaczyk Mar 18 at 16:15

Your Answer

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

Browse other questions tagged or ask your own question.