Consider the following situation:

  1. A Drupal 8 site using native SQL-storage (MySQL)
  2. custom_table is added to the same MySQL host as Drupal, either as a table in the Drupal system DB or as a table in a separate DB on the same host (Drupal supports either as the basis of a new entity). This table is the base_table of a custom content entity (custom_entity) as declared in custom_module. The entity is defined by extending \Drupal\Core\Entity\ContentEntityBase.
  3. Individual columns from custom_table are also mapped directly to Drupal fields on custom_entity using the baseFieldDefinitions() method in the entity definition.
  4. The custom_table is not declared in custom_module's hook_schema() because it is managed by external tools and may even have CRUD operations on it external to Drupal. The persistent_cache is disabled for custom_entity to account for this.
  5. custom_module is installed. The install routines automatically create entity/field storage definitions and related schema definitions as part of the installed state based on the custom_entity definition.
  6. custom_table grows full of data.
  7. The schema of custom_table needs to be updated (e.g. a new column added and mapped to a new custom_entity field, length increase to existing varchar string, etc.)

Because the schema of custom_table is not managed by Drupal how can Drupal be made aware of the schema updates in a way that is compatible with the native SQL entity and field storage that custom_entity uses?

Possible Approaches

Some ideas discussed in forums (here, here and the "Updating an existing entity type" notes here) involve ad-hoc workarounds such as direct updates to key_value DB records that seem dangerous.

TheEntityDefinitionUpdateManagerInterface seems to serve as a central place to deal with updates of this nature, but it also appears to couple updates to storage/schema definitions with the deployment of changes to actual DB schema. That said, I have had some success with snippets like this after updating the custom_entity definition appropriately:

$entity_type = \Drupal::entityTypeManager()->getDefinition('custom_entity');
$entity_definition_update_manager = \Drupal::entityDefinitionUpdateManager();

However, this method is documented for once-off use (not ongoing re-install use) so this feels like inappropriate use with possible side-effects.

I have also experimented with the entityDefinitionUpdateManager ::updateEntityType() and ::updateFieldStorageDefinition methods, as those appear safe to re-run, but they do not seem to update the installed schema definition appropriately.

I also suppose that a custom entity storage definition could be justified to deal with all this, but I assume that would require re-defining or re-wiring quite a few dependencies (notably the low-level SQL management) that otherwise work well with the native entity storage.

  • 1
    I think this is too broad for answers. You're asking for opinions and then going to try things out? It probably all depends on how that external system implements as well as what your entity definition looks like. – mradcliffe Jun 19 '19 at 17:11
  • 1
    @mradcliffe, I re-phrased the question to be more specific to SQL-based storage. I will also clarify my external entity structure a bit more. Perhaps the question is too detailed and needs to be whittled-down, but that's tricky to do when the interplay between an entity definition, the entity storage definition, the last installed schema definition, the actual schema management API is not yet clear. – rjacobs Jun 19 '19 at 17:36
  • 1
    Ok, I have re-factored the question in a significant way to better make the system details more clear and make the overall text much more objective. – rjacobs Jun 19 '19 at 23:20

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.