Last active
July 3, 2026 10:23
-
-
Save steffenr/e5115c4fe4e4c69fb076616edb07cb13 to your computer and use it in GitHub Desktop.
Updating text field length with existing data in Drupal 11
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * @file | |
| * Post update functions for my_module module. | |
| */ | |
| declare(strict_types=1); | |
| use Drupal\Core\Database\Database; | |
| use Drupal\field\FieldStorageConfigInterface; | |
| /** | |
| * Increase the maximum length of paragraph subheadline field to 512 characters. | |
| */ | |
| function my_module_post_update_increase_max_subheadline_length(array &$sandbox): void { | |
| $entity_type = 'paragraph'; | |
| $field_name = 'field_subheadline_text'; | |
| $new_length = 512; | |
| $value_column = "{$field_name}_value"; | |
| $tables = [ | |
| "{$entity_type}__{$field_name}", | |
| "{$entity_type}_revision__{$field_name}", | |
| ]; | |
| // 1. Alter the DB columns directly. Drupal's entity API refuses to change a | |
| // field's schema once it holds data | |
| // (SqlContentEntityStorageSchema::onFieldStorageDefinitionUpdate() throws | |
| // FieldStorageDefinitionUpdateForbiddenException), so we widen the columns | |
| // ourselves and then sync the tracked definitions below. Widening a varchar | |
| // never truncates existing values. | |
| $db_schema = Database::getConnection()->schema(); | |
| $column_spec = ['type' => 'varchar', 'length' => $new_length, 'not null' => FALSE]; | |
| foreach ($tables as $table) { | |
| if ($db_schema->tableExists($table)) { | |
| $db_schema->changeField($table, $value_column, $value_column, $column_spec); | |
| } | |
| } | |
| // 2. Sync the installed SQL storage schema so the entity definition update | |
| // manager stops reporting a mismatch. This is stored in the | |
| // "entity.storage_schema.sql" key-value collection under the key | |
| // "{entity_type}.field_schema_data.{field_name}" (see | |
| // SqlContentEntityStorageSchema::loadFieldSchemaData()). | |
| $kv = \Drupal::keyValue('entity.storage_schema.sql'); | |
| $schema_key = "{$entity_type}.field_schema_data.{$field_name}"; | |
| $field_schema = $kv->get($schema_key); | |
| if (is_array($field_schema)) { | |
| foreach ($field_schema as &$table_schema) { | |
| if (is_array($table_schema) | |
| && is_array($table_schema['fields'] ?? NULL) | |
| && is_array($table_schema['fields'][$value_column] ?? NULL) | |
| && array_key_exists('length', $table_schema['fields'][$value_column]) | |
| ) { | |
| $table_schema['fields'][$value_column]['length'] = $new_length; | |
| } | |
| } | |
| $kv->set($schema_key, $field_schema); | |
| } | |
| // 3. Update the active field storage config. Use the raw config factory to | |
| // bypass the entity API (a FieldStorageConfig::save() would re-trigger the | |
| // forbidden-schema-change check from step 1). | |
| \Drupal::configFactory() | |
| ->getEditable("field.storage.{$entity_type}.{$field_name}") | |
| ->set('settings.max_length', $new_length) | |
| ->save(); | |
| // 4. Update the last-installed field storage definition so it matches the | |
| // active config. | |
| $repository = \Drupal::service('entity.last_installed_schema.repository'); | |
| $definitions = $repository->getLastInstalledFieldStorageDefinitions($entity_type); | |
| if (isset($definitions[$field_name]) && $definitions[$field_name] instanceof FieldStorageConfigInterface) { | |
| $definitions[$field_name]->setSetting('max_length', $new_length); | |
| $repository->setLastInstalledFieldStorageDefinitions($entity_type, $definitions); | |
| } | |
| // 5. Clear cached definitions so the new schema takes effect immediately. | |
| \Drupal::service('entity_type.manager')->clearCachedDefinitions(); | |
| \Drupal::service('entity_field.manager')->clearCachedFieldDefinitions(); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment