Skip to main content
Updating the Drupal 9 entity schema

Entities allow you to manage data in one or more tables. During the development of websites or applications, we are generally required to create entities.

These entities evolve according to requirements. When this occurs at the very beginning of development (without significant information in the database), we can empty our tables and use the Devel Entity Updates Updates module to update the table schemas.

However, if the need to update the table schema arises later, Drupal does not currently have APIs to do this. To fix this, we need to write our own update functions.

Our update logic must be implemented in the hook_update_N  hook. The basic logic is as follows: We must retrieve the data from the table, empty it (usually just the column), apply the update, and re-inject the data.

Case study 1: setting the length (max_length) of a varchar column.

We have a field with the following configuration:

...
$fields['name'] = BaseFieldDefinition::create('string')->setLabel(t('Name'))->setDescription(t('The name of the Site type datas entity.'))->setSettings([
      'max_length' => 50,
      'text_processing' => 0
    ])->setDefaultValue('')->setDisplayOptions('view', [
      'label' => 'above',
      'type' => 'string',
      'weight' => -4
    ])->setDisplayOptions('form', [
      'type' => 'string_textfield',
      'weight' => -4
    ])->setDisplayConfigurable('form', TRUE)->setDisplayConfigurable('view', TRUE)->setRequired(TRUE)->setTranslatable(true);
...

We want to change the max_length to 250.

function __blockscontent_update_name_max_length($entity_type_id) {
  /**
   *
   * @var \Drupal\Core\Entity\Sql\SqlContentEntityStorage $entityStorage
   */
  $entityStorage = \Drupal::entityTypeManager()->getStorage($entity_type_id);
  
  // Retrieve existing field data.
  $database = \Drupal::database();
  $table = $entity_type_id . '_field_data';
  $names = $database->select($table, 'et')->fields('et', [
    'id',
    'langcode',
    'name'
  ])->execute()->fetchAll(\PDO::FETCH_ASSOC);
  // Remove data from the column.
  $database->update($table)->fields([
    'name' => NULL
  ])->execute();
  //
  // si les revisions sont activées.
  if ($entityStorage->getRevisionTable()) {
    $table_revision = $entity_type_id . "_field_revision";
    $names_revision = $database->select($table_revision, 'et')->fields('et', [
      'id',
      'langcode',
      'name'
    ])->execute()->fetchAll(\PDO::FETCH_ASSOC);
    $database->update($table_revision)->fields([
      'name' => NULL
    ])->execute();
  }
  
  // Remove old definition field.
  $updateManager = \Drupal::entityDefinitionUpdateManager();
  $storagedef = $updateManager->getFieldStorageDefinition('name', $entity_type_id);
  $updateManager->uninstallFieldStorageDefinition($storagedef);
  // Load new definition field in code.
  /**
   *
   * @var \Drupal\Core\Entity\EntityFieldManager $fieldManager
   */
  $fieldManager = \Drupal::service('entity_field.manager');
  $fields = $fieldManager->getFieldStorageDefinitions($entity_type_id);
  $updateManager->installFieldStorageDefinition('name', $entity_type_id, "gestion_tache", $fields['name']);
  // Restore entity data in the new schema.
  foreach ($names as $name) {
    $database->update($table)->fields([
      'name' => $name['name']
    ])->condition('id', $name['id'])->condition('langcode', $name['langcode'])->execute();
  }
  // restore revision
  if ($entityStorage->getRevisionTable())
    foreach ($names_revision as $name) {
      $database->update($table_revision)->fields([
        'name' => $name['name']
      ])->condition('id', $name['id'])->condition('langcode', $name['langcode'])->execute();
    }
}
/**
 * Update value max_length from 50 to 250.
 *
 * implement hook_update_8001
 *
 * @see https://www.drupal.org/node/2554097
 */
function blockscontent_update_8001() {
  __blockscontent_update_name_max_length('blocks_contents');
}
Profile picture for user admin Stephane K

Écrit le

Il y'a 2 years
Modifié
Il y'a 2 weeks
Loading ...
WhatsApp
Support Habeuk : +237 694 900 622
WhatsApp Send