Updating the storage definition of entities that already have content in Drupal 8
Recently, I was asked to increase the length of a text field. Relatively straight forward, except there was already content.
The SQL storage cannot change the schema for an existing field
I understand the reasoning behind prohibiting an automatic operation, but if I'm making the change explicitly in code, it should just work. Here's how I got around it:
/**
* Increase FIELD size to 50.
*/
function MODULE_update_8XXX() {
$database = \Drupal::database();
// Retrieve existing field data.
$entity_type = 'ENTITY_TYPE';
$field = 'FIELD_NAME';
$tables = [
"{$entity_type}__$field",
"{$entity_type}_revision__$field",
];
$existing_data = [];
foreach ($tables as $table) {
// Get the old data.
$existing_data[$table] = $database->select($table)
->fields($table)
->execute()
->fetchAll(PDO::FETCH_ASSOC);
// Wipe it.
$database->truncate($table)->execute();
}
$field_storage_configs = \Drupal::entityTypeManager()
->getStorage('field_storage_config')
->loadByProperties([
'field_name' => $field,
]);
foreach ($field_storage_configs as $field_storage) {
$new_field_storage = $field_storage->toArray();
$new_field_storage['settings']['max_length'] = 50;
$new_field_storage = FieldStorageConfig::create($new_field_storage);
$new_field_storage->original = $new_field_storage;
$new_field_storage->enforceIsNew(FALSE);
$new_field_storage->save();
}
// Restore the data.
foreach ($tables as $table) {
$insert_query = $database
->insert($table)
->fields(array_keys(end($existing_data[$table])));
foreach ($existing_data[$table] as $row) {
$insert_query->values(array_values($row));
}
$insert_query->execute();
}
}
Loosely inspired by https://www.drupal.org/node/2554097
Written by Jon Peck
Related protips
Have a fresh tip? Share with Coderwall community!
Post
Post a tip
Best
#Drupal
Authors
Sponsored by #native_company# — Learn More
#native_title#
#native_desc#