web-dev-qa-db-ja.com

日付フィールドを正しく移行する方法は?

分類法の用語をレガシーデータベースから私のdrupal 7インストールに移行します。これはほぼ期待どおりに機能しています。基本的には、次のような移行例で説明されているように、マッピングを定義します。

_$this->addFieldMapping('name', 'legacy_name');
_

しかし、日付を移行しようとすると、完全に失敗します。これは動作しません:

_$this->addFieldMapping('field_date', 'valid_from');
_

少し掘り下げた後、私は 見つけた _Date Migration_モジュールを有効にする必要がありました。しかし、それでも、これはまったく機能しません。私はいくつかの 日付移行のサンプルコード を発見し、prepareRow()関数の日付フィールドを再フォーマットする必要があることを発見しました。しかし、その機能は文書化されていません。リンクされた例はまったく機能しません。

私の現在のコードは次のようになります:

_abstract class MyBasicMigration extends Migration {
  public function __construct() {
    parent::__construct();
  }
}

class MyMigration extends MyBasicMigration {
  public function __construct() {
    parent::__construct();

    #[...]

    $this->destination = new MigrateDestinationTerm('mystuff');
    # this works:
    $this->addFieldMapping('name', 'legacy_name'); 
    # this does not:
    $this->addFieldMapping('field_date', 'valid_from'); 
  }

  public function prepareRow($current_row) {
    # checks for malformed date strings in DB and converts to datetime type
    if (($current_row->valid_from = strtotime($current_row->valid_from)) === false) {
      $current_row->valid_from = strtotime('1970-02-01');
    }
    if (($current_row->valid_to = strtotime($current_row->valid_to)) === false) {
      $current_row->valid_to = strtotime('2037-12-31');
    }
    # converts the date to YYYY-mm-dd format
    $format = 'Y-m-d';
    $current_row->valid_from = date($format, $current_row->valid_from);
    $current_row->valid_to = date($format, $current_row->valid_to);
    # creates a date field for the valid_from/to migration mapping
    $current_row->valid_from = array(
      'value' => (string) $current_row->valid_from,
      'value2' => (string) $current_row->valid_to,
      'timezone' => DateMigrateFieldHandler::arguments('Europe/Berlin'),
      'timezone_db' => DateMigrateFieldHandler::arguments('Europe/Berlin'),
      'date_type' => 'datetime',
    );
    $current_row->valid_from = drupal_json_encode($current_row->valid_from);
    # debug result output
    watchdog("PW_TEST", $current_row->valid_from, $variables = NULL, WATCHDOG_DEBUG, $link = NULL);
  }
_

データベースの日付形式は、_2013-12-31_のような形式の文字列です。

prepareRow()関数はまったく機能しているようで、watchdog()出力は非常に良好に見えます。

_{"value":"1970-02-01","value2":"2013-12-31","timezone":{"timezone":"Europe\/Berlin","timezone_db":"UTC","rrule":null,"language":null},"timezone_db":{"timezone":"Europe\/Berlin","timezone_db":"UTC","rrule":null,"language":null},"date_type":"datetime"}
_

ご覧のとおり、返されたJSON文字列には正しい日付が含まれています。しかし、ある時点で、フィールド_valid_from_および_valid_to_で移行マッピングが失敗します。

移行された分類用語でprint_r()を実行すると、次のようになります。

_[field_date] => Array
    (
        [und] => Array
            (
                [0] => Array
                    (
                        [value] => 
                        [value2] => 
                        [timezone] => Europe/Berlin
                        [timezone_db] => Europe/Berlin
                        [date_type] => datetime
                    )
            )
    )
_

JSONオブジェクトが正しくマッピングされ、_date_type_およびtimezoneが正しく表示されるようになりました。しかし、私のデートはどこに行ったのですか?何か案は?

私はこれに一日中取り組んでおり、コードに問題はありません。ヒントをありがとう!

3
Afr

これはひどいもので、完全に文書化されていません。しかし私は見つけました:

_# creates a date field for the valid_from/to migration mapping
$current_row->valid_from = array(
  'from' => (string) $current_row->valid_from,
  'to' => (string) $current_row->valid_to,
  //'timezone' => DateMigrateFieldHandler::arguments('Europe/Berlin'),
  //'timezone_db' => DateMigrateFieldHandler::arguments('Europe/Berlin'),
  //'date_type' => 'datetime',
);
_

上記のコードに関する2つの問題が解決されました。

  1. 日付を含む配列含まなければならないフィールドfromおよびto。それ以外の場合は、日付範囲を理解できません。これは日付移行の例で見ましたが、フィールド名がマッピングにとって重要であるとは思っていませんでした。 (私はむしろターゲット名valueと_value2_を使用しました。)
  2. 配列含まないでくださいタイムゾーンと日付タイプに関する情報。 DateMigrateFieldHandler::prepare()がそれを行います。

上記の作業コードは次のようになります。

_[field_date] => Array
    (
        [und] => Array
            (
                [0] => Array
                    (
                        [value] => 1970-02-01 00:00:00
                        [value2] => 2013-12-31 00:00:00
                        [timezone] => Europe/Berlin
                        [timezone_db] => Europe/Berlin
                        [date_type] => datetime
                    )
            )
    )
_

修繕。 :)

4
Afr

これはまだ十分に文書化されていませんが、私はこの問題につまずきます...

与えられた解決策はほぼ正しいですが、最終的な配列はdrupal_json_encode()関数を介して渡される必要があります:

# creates a date field for the valid_from/to migration mapping
$current_row->valid_from = drupal_json_encode(
  array(
    'from' => (string) $current_row->valid_from,
    'to' => (string) $current_row->valid_to,
    //'timezone' => DateMigrateFieldHandler::arguments('Europe/Berlin'),
    //'timezone_db' => DateMigrateFieldHandler::arguments('Europe/Berlin'),
    //'date_type' => 'datetime',
 ));
2
user32205