整数のコンテンツフィールドを持つコンテンツタイプがあります。フィールドには浮動小数点データを含める必要があります。フィールドタイプを整数から10進数に変更する最も簡単な方法は何ですか?(変換する必要がある既存のノードは何千もあります)。
整数のコンテンツフィールドを持つコンテンツタイプがあります。フィールドには浮動小数点データを含める必要があります。フィールドタイプを整数から10進数に変更する最も簡単な方法は何ですか?(変換する必要がある既存のノードは何千もあります)。
回答:
以前のすべての提案を1つの便利なチャンクにマージするだけです。
// Change this to your field name, obvs.
$field = 'field_myfieldname';
// Update the storage tables
$tables = array('field_data', 'field_revision');
foreach ($tables as $table) {
$tablename = $table .'_'. $field;
$fieldname = $field .'_value';
db_change_field($tablename, $fieldname, $fieldname, array(
'type' => 'numeric',
'precision' => 10,
'scale' => 2,
'not null' => FALSE,
));
}
// Fetch the current field configuration
$field_config = db_query("SELECT data FROM {field_config} WHERE field_name = :field_name", array(
':field_name' => $field,
))
->fetchObject();
$data = unserialize($field_config->data);
// Update the settings entry
$data['settings'] = array(
'precision' => 10,
'scale' => 2,
'decimal_separator' => '.',
);
// Store the new field config, update the field type at the same time
db_update('field_config')
->fields(array(
'data' => serialize($data),
'type' => 'number_decimal',
))
->condition('field_name', $field)
->execute();
// If you are confident about what bundles have instances of this field you can
// go straight to the db_query with a hardcoded entity_type / bundle.
$instances = field_info_field_map();
foreach ($instances[$field]['bundles'] as $entity_type => $bundles) {
foreach ($bundles as $bundle) {
// Fetch the field instance data
$field_config_instance = db_query("SELECT data FROM {field_config_instance}
WHERE field_name = :field_name
AND entity_type = :entity_type
AND bundle = :bundle", array(
':field_name' => $field,
':entity_type' => $entity_type,
':bundle' => $bundle,
))
->fetchObject();
$data = unserialize($field_config_instance->data);
// Update it with the new display type
$data['display']['default']['type'] = 'number_decimal';
// Store it back to the database
db_update('field_config_instance')
->fields(array('data' => serialize($data)))
->condition('field_name', $field)
->condition('entity_type', $entity_type)
->condition('bundle', $bundle)
->execute();
}
}
Drupalの組み込み機能を使用してフィールドタイプdb_change_field()を変更することをお勧めします。
db_change_field('field_data_field_number', 'field_number_value', 'field_number_value', array(
'type' => 'numeric',
'precision' => 10,
'scale' => 2,
'not null' => FALSE,
));
ヘルパーモジュールでこれを処理するためのコードをいくつか書いたところです。http://cgit.drupalcode.org/helper/tree/lib/FieldChangeHelper.php?h = 7.x-1.x
FieldChangeHelper::changeType('my_int_field_name', 'number_decimal');
ほとんどの単純なケースとフィールドでは問題なく機能しますが、徹底的にテストする必要があります。現在、フィールドフォーマッタも更新されていないため、これを実行した後、フィールドの表示設定を確認する必要があります。
上記のDave Reids drupal.org/project/helperモジュールは、優れたシンプルなソリューションです。
上記にコメントを追加できないので、ここに手順を投稿してください。
1)ヘルパーモジュールをダウンロードして有効にする
2)新しいファイルを作成します:changeIntField.php
<?php
FieldChangeHelper::changeType('my_int_field_name', 'number_decimal');
?>
3)drupalがインストールされているルートフォルダーにファイルを保存します
4)drush scr changeIntField.php
5)不要になったファイルchangeIntFiled.phpを削除します。
6)フィールドが使用されているノード/エンティティの表示形式を編集します。
7)ビューの編集-フィールドが使用される場所と、ここでも表示形式設定を修正します。
drush scr
drush php-eval "FieldChangeHelper::changeType('my_int_field_name', 'number_decimal');"
ですか?
Drupal 7コンテンツフィールドのタイプを整数から10進数に変更するのは非常に簡単です。新しいフィールドを作成してから定義をコピーする必要はありません。私は次の3つのステップを使用しました。
MySQLを使用して、フィールドのテーブルの名前と、フィールドの値が格納されているそのテーブル内のフィールドの名前を見つけます。
MySQL変更ステートメントを使用して、フィールドのデータ型を変更します。
ALTER TABLE field_data_field_myfield MODIFY field_myfield_value decimal(10,2) ;
Drupalでフィールド定義を変更します。
UPDATE field_config SET type = 'number_decimal' WHERE field_name = 'field_myfield';
手順1〜3で十分です。ただし、場合によっては、field_configテーブルの整数フィールドと10進数フィールドのプロパティを比較して、変更が必要なものが他にあるかどうかを確認すると便利な場合がありますSELECT id, field_name, type, CONVERT(data USING utf8) FROM field_config WHERE type like 'number_%'
。
各フィールドにはfield_revision_field_ {field_name}と呼ばれる別のテーブルがあり、このテーブルのmysql列タイプも変更されることに注意してください
また、10進数フィールドには異なる設定が必要です。次のスクリプトを使用して、フィールド設定のシリアル化を解除して変更し、再度シリアル化してください。2つのテーブルfield_configとfield_config_instanceがあります。以下はfield_config用です
$s = unserialize('field_config table serialize string');
$s['settings'] = array (
'precision' => '20',
'scale' => '0',
'decimal_separator' => '.',
);
print serialize($s);
ここにフィールド設定インスタンスがあります:
$s = unserialize('field_config_instance table serialize string');
$s['display']['default']['type'] = 'number_decimal';
print serialize($s);
注:フィールドには複数のインスタンスが含まれる場合があり、すべてのインスタンスに次のコードを使用する必要があります。
Drupalのキャッシュをクリアし、フィールド設定に進み、フィールドを編集して保存します。エラーが表示されない場合は、おそらく問題ありません:)
「field_margin_percentage」というフィールドを10進数に変更する必要がありました
手順1-データベースのフィールドを更新しました
db_change_field('field_data_field_margin_percentage', 'field_margin_percentage_value', 'field_margin_percentage_value', array(
'type' => 'numeric',
'precision' => 10,
'scale' => 2,
'not null' => FALSE,
));
ステップ2-フィールドが正しいハンドラーを認識するようにfield_configを更新します
db_query("UPDATE field_config SET type = 'number_decimal' WHERE field_name = 'field_margin_percentage'");
手順3-field_configから既存の「データ」列を取得し、10進設定を追加する
$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)
ステップ4-field_config_instanceから既存の「データ」列を取得し、10進設定を追加する
$s = unserialize('a:7:{s:5:"label";s:17:"Margin Percentage";s:6:"widget";a:5:{s:6:"weight";s:2:"13";s:4:"type";s:6:"number";s:6:"module";s:6:"number";s:6:"active";i:0;s:8:"settings";a:0:{}}s:8:"settings";a:7:{s:3:"min";s:1:"0";s:3:"max";s:3:"100";s:6:"prefix";s:0:"";s:6:"suffix";s:0:"";s:26:"commerce_user_profile_pane";i:0;s:35:"commerce_user_profile_pane_required";i:0;s:18:"user_register_form";b:0;}s:7:"display";a:1:{s:7:"default";a:5:{s:5:"label";s:5:"above";s:4:"type";s:14:"number_integer";s:6:"weight";s:2:"12";s:8:"settings";a:4:{s:18:"thousand_separator";s:1:" ";s:17:"decimal_separator";s:1:".";s:5:"scale";i:0;s:13:"prefix_suffix";b:1;}s:6:"module";s:6:"number";}}s:8:"required";i:0;s:11:"description";s:115:"The Paddy\'s Seals % of this sale. You can enter this OR the Margin Value. The other one will be calculated for you.";s:13:"default_value";a:1:{i:0;a:1:{s:5:"value";s:1:"0";}}}');
$s['display']['default']['type'] = 'number_decimal';
print serialize($s);
ステップ5-上記のシリアル化された文字列を使用して、field_configおよびfield_config_instanceの「データ」列を更新します
db_query('update field_config set data=\'a:7:{s:12:"translatable";s:1:"0";s:12:"entity_types";a:0:{}s:8:"settings";a:3:{s:9:"precision";s:2:"10";s:5:"scale";s:1:"2";s:17:"decimal_separator";s:1:".";}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";}\' where field_name=\'field_margin_percentage\'');
db_query('update field_config_instance set data=\'a:7:{s:5:"label";s:17:"Margin Percentage";s:6:"widget";a:5:{s:6:"weight";s:2:"13";s:4:"type";s:6:"number";s:6:"module";s:6:"number";s:6:"active";i:0;s:8:"settings";a:0:{}}s:8:"settings";a:7:{s:3:"min";s:1:"0";s:3:"max";s:3:"100";s:6:"prefix";s:0:"";s:6:"suffix";s:0:"";s:26:"commerce_user_profile_pane";i:0;s:35:"commerce_user_profile_pane_required";i:0;s:18:"user_register_form";b:0;}s:7:"display";a:1:{s:7:"default";a:5:{s:5:"label";s:5:"above";s:4:"type";s:14:"number_decimal";s:6:"weight";s:2:"12";s:8:"settings";a:4:{s:18:"thousand_separator";s:1:" ";s:17:"decimal_separator";s:1:".";s:5:"scale";i:0;s:13:"prefix_suffix";b:1;}s:6:"module";s:6:"number";}}s:8:"required";i:0;s:11:"description";s:115:"The Paddy-s Seals % of this sale. You can enter this OR the Margin Value. The other one will be calculated for you.";s:13:"default_value";a:1:{i:0;a:1:{s:5:"value";s:1:"0";}}}\' where field_name=\'field_margin_percentage\'');
これが私がupdate_hook_N()でDrupal 7を実行した方法です。
計画では、 "field_ui_current_salary"と呼ばれる1つのフィールドをDECIMAL(10)からDECIMAL(10,2)に変更し、小数をまったく使用せずに2つの小数点を許可しました。
/**
* Changing Database Currenty Salary field to allow decimals.
* Replace MYMODULE with your module's name and number N with your next incremented value.
*/
function MYMODULE_update_7001() {
// field_ui_current_salary scale = 2 in field_config table.
// Use your 'data' value for $new_data from 'field_config' table for your field and just change where 'scale' is from 0 to 2 (or your desired number of decimals)
$new_data = 'a:8:{s:12:"entity_types";a:0:{}s:17:"field_permissions";a:1:{s:4:"type";i:0;}s:7:"indexes";a:0:{}s:8:"settings";a:5:{s:3:"max";d:99999999.989999995;s:3:"min";d:-99999999.989999995;s:9:"precision";i:10;s:16:"profile2_private";b:0;s:5:**"scale";i:2;**}s:12:"translatable";i: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_ui_current_salary";a:2:{s:6:"amount";s:30:"field_ui_current_salary_amount";s:8:"currency";s:32:"field_ui_current_salary_currency";}}s:19:"FIELD_LOAD_REVISION";a:1:{s:38:"field_revision_field_ui_current_salary";a:2:{s:6:"amount";s:30:"field_ui_current_salary_amount";s:8:"currency";s:32:"field_ui_current_salary_currency";}}}}}s:12:"foreign keys";a:0:{}s:2:"id";s:3:"372";}';
db_query('UPDATE {field_config} SET data = :new_data WHERE field_name = :salary;', array(':new_data' => $new_data, ':salary' => 'field_ui_current_salary'));
// field_data_field_ui_current_salary and its revision copy -> DECIMAL(10,2)
db_query("ALTER TABLE {field_data_field_ui_current_salary} MODIFY field_ui_current_salary_amount DECIMAL(10,2);");
db_query("ALTER TABLE {field_revision_field_ui_current_salary} MODIFY field_ui_current_salary_amount DECIMAL(10,2);");
cache_clear_all();
}
元の質問はDrupal 7に関するものでしたが、多くの人がDrupal 8でこれを行う方法を疑問に思っていると思います。残念ながら、現時点でこれを行うための適切な方法はありません。最も悪い方法は、フィールド(およびフィールドに含まれるデータ)を単に削除し、Drupalに最初から再作成させることです。
私はより良い解決策を見つけようとしているので、それが利用できる場合はここに投稿します:https : //www.drupal.org/node/2843108