web-dev-qa-db-ja.com

フィールドタイプを整数から10進数に変更するにはどうすればよいですか?

整数のコンテンツフィールドを持つコンテンツタイプがあります。フィールドには浮動小数点データを含める必要があります。フィールドタイプを整数から10進数に変更する最も簡単な方法は何ですか? (変換する必要がある既存のノードは何千もあります)。


このコメントこのコメント で解決策を見つけました。最高ですか?

7
Druvision

以前のすべての提案を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();

  }
}
8
KingAndy

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,
));
5
heddn

上記の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)ビューの編集-フィールドが使用される場所と、ここでも表示形式設定を修正します。

4
Alauddin

Helper modulehttp://cgit.drupalcode.org/helper/tree/lib/FieldChangeHelper.php?h=7でこれを処理するためのコードをいくつか書きました。 .x-1.x

FieldChangeHelper::changeType('my_int_field_name', 'number_decimal');

ほとんどの単純なケースとフィールドでは問題なく機能しますが、徹底的にテストする必要があります。現在、フィールドフォーマッタも更新されていないため、これを実行した後、フィールドの表示設定を確認する必要があります。

4
Dave Reid

Drupal 7コンテンツフィールドのタイプを整数から10進数に変更するのは非常に簡単です。新しいフィールドを作成してから定義をコピーする必要はありません。次の3つの手順を使用しました。

  1. MySQLを使用して、フィールドのテーブルの名前と、フィールドの値が格納されているテーブル内のフィールドの名前を見つけます。

  2. MySQL変更ステートメントを使用して、フィールドのデータ型を変更します。
    ALTER TABLE field_data_field_myfield MODIFY field_myfield_value decimal(10,2) ;

  3. 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_%'

2
Druvision

各フィールドには、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のキャッシュをクリアし、フィールド設定に進み、フィールドを編集して保存します。エラーが表示されない場合は、おそらく問題ありません:)

2
Sina Salek

「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\'');
1
Bryan Gruneberg

Drupal 7をupdate_hook_N()で実行した方法は次のとおりです。

計画では、 "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();
}
0
Ales Rebec

元の質問はDrupal 7に関するものでしたが、Drupal 8.でこれを行う方法を多くの人々が疑問に思っていると思います。残念ながら、現時点でこれに適した方法です。最も悪い方法は、フィールド(およびフィールドに含まれるデータ)を削除し、Drupalを最初から作成し直す)ことです。

私はより良い解決策を見つけようとしているので、それが利用できる場合はいつでもここに投稿します: https://www.drupal.org/node/2843108

0
Dane Powell