Problem/Motivation
In the discussion of #2997960: Missing taxonomy hierarchy items in 8.6.0 after running taxonomy_update_8502, it seems that some site maintainers applied the update function after updating to Drupal 8.6.0, then applied it again when 8.6.1 was released. The first update added a table, and the second update threw an exception when it tried to create a table that was already there.
One suggestion was to add a truncate
to the update function. This would solve the immediate problem for some users, allowing the update function to complete.
@plach noted that adding the truncate
could hide other problems and that the best practice is to start from a database that has not had any failed update attempts.
Proposed resolution
If an update function creates a database table, then it should fail gracefully, with a useful error message, if that table already exists.
Add a helper function so that update functions can do this consistently and conveniently.
Remaining tasks
User interface changes
This will add a warning message, presented to users during updates when update functions attempt to create tables that already exist.
API changes
Add a new helper function available to update functions.
Data model changes
None
Comments
Comment #2
benjifisherAn update function can create a table directly, using
db_create_table()
orDrupal\Core\Database\Schema::createTable()
, or it might create a table indirectly. For example,taxonomy_update_8501()
usesupdateFieldStorageDefinition()
to create a new field on thetaxonomy_term
entity, which creates a new table.I am not sure what the best way to do this is. Perhaps the update function should have an explicit
try
, and call the proposed helper function from thecatch
clause.Comment #3
catch#2 seems like a good plan to start with.
Comment #4
plachMy original idea was to add an helper class with static methods. Here we would add a method to check whether a table already exists. If this were the case, the method would display an useful error message suggesting to remove or maybe just rename (for good measure) the table and run the update again. It would also throw an exception to ensure the current update is not marked as applied.
The update function would just have to call the helper method at the beginning of the execution.