Created
February 9, 2025 17:07
-
-
Save drubb/4430370f91cf329f184fdebca141dcf2 to your computer and use it in GitHub Desktop.
Drush script to update changed field definitions for a price field, switched from integer to decimal. The script is run after the related code changes have been deployed, it updates the underlying database structures.
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 declare(strict_types=1); | |
/** | |
* @file | |
* Drush script to change the price fields from integer to decimal. | |
*/ | |
use Drupal\Core\Database\Database; | |
// Check whether there are changes to field definitions. | |
$change_list = \Drupal::entityDefinitionUpdateManager()->getChangeSummary(); | |
if (empty($change_list)) { | |
\Drupal::messenger() | |
->addMessage(t('There are no changes to field definitions.')); | |
return; | |
} | |
// Backup and clear the related tables. | |
$tables = ['node__field_prices', 'node_revision__field_prices']; | |
foreach ($tables as $table) { | |
// Copy the table to a backup table. | |
copy_table($table, $table . '_backup'); | |
// Truncate the original table. | |
truncate_table($table); | |
} | |
// Make the changes to the field definitions. There's just one field. | |
$field_definition = \Drupal::entityDefinitionUpdateManager() | |
->getFieldStorageDefinition('field_prices', 'node'); | |
\Drupal::entityDefinitionUpdateManager() | |
->updateFieldStorageDefinition($field_definition); | |
// Restore the data and drop the backup tables. | |
foreach ($tables as $table) { | |
restore_table($table . '_backup', $table); | |
drop_table($table . '_backup'); | |
} | |
/** | |
* Function to duplicate a table in the database. | |
* | |
* @param string $existing_table_name | |
* The name of the existing table. | |
* @param string $new_table_name | |
* The name of the new table. | |
*/ | |
function copy_table(string $existing_table_name, string $new_table_name): void { | |
// Get the database connection. | |
$connection = Database::getConnection(); | |
// Build the query to copy the table structure and data. | |
$query = "CREATE TABLE $new_table_name AS SELECT * FROM $existing_table_name"; | |
try { | |
// Execute the query. | |
$connection->query($query); | |
\Drupal::messenger() | |
->addMessage(t('Table @new_table_name has been created successfully.', ['@new_table_name' => $new_table_name])); | |
} | |
catch (\Exception $e) { | |
\Drupal::messenger() | |
->addError(t('Failed to create table: @message', ['@message' => $e->getMessage()])); | |
exit(1); | |
} | |
} | |
/** | |
* Function to truncate a table in the database. | |
* | |
* @param string $table_name | |
* The name of the table to truncate. | |
*/ | |
function truncate_table(string $table_name): void { | |
// Get the database connection. | |
$connection = Database::getConnection(); | |
// Build the query to truncate the table. | |
$query = "TRUNCATE TABLE $table_name"; | |
try { | |
// Execute the query. | |
$connection->query($query); | |
\Drupal::messenger() | |
->addMessage(t('Table @table_name has been truncated successfully.', ['@table_name' => $table_name])); | |
} | |
catch (\Exception $e) { | |
\Drupal::messenger() | |
->addError(t('Failed to truncate table: @message', ['@message' => $e->getMessage()])); | |
exit(1); | |
} | |
} | |
/** | |
* Function to restore data from a backup table to the original table. | |
* | |
* @param string $backup_table_name | |
* The name of the backup table. | |
* @param string $original_table_name | |
* The name of the original table. | |
*/ | |
function restore_table(string $backup_table_name, string $original_table_name): void { | |
// Get the database connection. | |
$connection = Database::getConnection(); | |
// Build the query to restore the data from the backup table. | |
$query = "INSERT INTO $original_table_name SELECT * FROM $backup_table_name"; | |
try { | |
// Execute the query. | |
$connection->query($query); | |
\Drupal::messenger() | |
->addMessage(t('Data has been restored from @backup_table_name to @original_table_name.', [ | |
'@backup_table_name' => $backup_table_name, | |
'@original_table_name' => $original_table_name, | |
])); | |
} | |
catch (\Exception $e) { | |
\Drupal::messenger() | |
->addError(t('Failed to restore data: @message', ['@message' => $e->getMessage()])); | |
exit(1); | |
} | |
} | |
/** | |
* Function to drop a table in the database. | |
* | |
* @param string $table_name | |
* The name of the table to drop. | |
*/ | |
function drop_table(string $table_name): void { | |
// Get the database connection. | |
$connection = Database::getConnection(); | |
// Build the query to drop the table. | |
$query = "DROP TABLE $table_name"; | |
try { | |
// Execute the query. | |
$connection->query($query); | |
\Drupal::messenger() | |
->addMessage(t('Table @table_name has been dropped successfully.', ['@table_name' => $table_name])); | |
} | |
catch (\Exception $e) { | |
\Drupal::messenger() | |
->addError(t('Failed to drop table: @message', ['@message' => $e->getMessage()])); | |
exit(1); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This Gist is meant for fields defined programmatically, where the necessary changes have been made in code already.
To change the field settings for a field defined in the UI, the schema change must be run explicitly. Example:
Additionally, it might be necessary to adjust any keys using this field.