Изменение типа поля с integer на decimal

Главные вкладки

Аватар пользователя Mr.Alinaki@drupal.org Mr.Alinaki@drup... 5 июля 2014 в 16:07

Добрый день!

Из-за недопонимания при разработке системы складского учёта, поле "Количество товара" я сделал целым. В процессе работы оказалось, что списание топлива и иных жидкостей происходит долями литра. Встал вопрос о смене типа поля на десятичное.

Я наткнулся на ответ на stackexchange: http://drupal.stackexchange.com/questions/79378/changing-a-field-type-fr...

Там рекомендовали использовать db_change_field совместно с десериализацией существующих настроек, внесением нужных изменений, и сериализацией с сохранением в базу. Собственно, кусок кода:

<?php
$current_field_config 
'a:7:{s:12:"translatable";s:1:"0";s:12:"entity_types";a:0:{}s:8:"settings";a:0:{}s:7:"storage";a:5:{s:4:"type";s:17:"field_sql_storage";s:8:"settings";a:0:{}s:6:"module";s:17:"field_sql_storage";s:6:"active";s:1:"1";s:7:"details";a:1:{s:3:"sql";a:2:{s:18:"FIELD_LOAD_CURRENT";a:1:{s:34:"field_data_field_margin_percentage";a:1:{s:5:"value";s:29:"field_margin_percentage_value";}}s:19:"FIELD_LOAD_REVISION";a:1:{s:38:"field_revision_field_margin_percentage";a:1:{s:5:"value";s:29:"field_margin_percentage_value";}}}}}s:12:"foreign keys";a:0:{}s:7:"indexes";a:0:{}s:2:"id";s:3:"161";}';

$s unserialize($current_field_config);

$s['settings'] = array (
    
'precision' => '10',
    
'scale' => '2',
    
'decimal_separator' => '.',
);

print 

serialize($s); // This will give you the new value for the data column (see below)
?>

Для field_config и field_config_instance.

И тут начались проблемы.

Во первых, они забыли про таблицу field_revision_field_NAME, а во вторых, после проведения указанной выше операции, десериализация настроек поля друпалом стала невозможна, о чём он мне любезно сообщил fatal error'ом в строке 479 field.class.php: несоответствие аргументов операции. Настройки не извлекались из сериализованной строки.

Я решил проблему, создав дополнительные поля с нужными настройками и просто скопировав сериализованные строки с настройками из них. После чего провёл db_change_field с запросом на изменение типа поля в field_config:

<?php
function helper_update_7001() {
  
// drupal_set_message('Will change field_number settings');

  

db_query("UPDATE field_config SET type = 'number_decimal' WHERE field_name = 'field_number'");

  

db_change_field('field_data_field_number''field_number_value''field_number_value', array(
    
'type' => 'numeric',
    
'precision' => 16,
    
'scale' => 3,
    
'not null' => FALSE,
  ));

  

db_change_field('field_revision_field_number''field_number_value''field_number_value', array(
    
'type' => 'numeric',
    
'precision' => 16,
    
'scale' => 3,
    
'not null' => FALSE,
  ));

  

field_cache_clear(TRUE);

  

// Manually copy config and instance!
}
?>

Собственно, вопрос: что я сделал не так в сериализации настроек полей?