暴力匯入大量資料到drupal系統

Posted by on | |


稱之為“暴力”,是因為不透過 drupal 的模組或api,反而是要直接存取資料庫,
優點:是自己可以控制想要存取的欄位,
缺點:也是自己可以控制想要存取的欄位,一不注意,資料可能就亂了。

看了一下,drupal api - node_save(),簡記幾個重要動作:

  1. 處理資料
  2. 處理版本
  3. 處理cache



所以要自己寫進資料庫,就要記得對這些處理也做控制。

關於d7的資料庫結構,簡單介紹幾個table:

//關於欄位結構的table
node_type:內容類型的定義
field_config:各個欄位的定義
field_config_instance:內容類型 vs 欄位 的關聯表

//關於資料內容的table
node:資料的title欄位,包括“是否發表”等椌制node的欄位
field_data_body:資料的body欄位
field_data_{欄位machine_name}:資料的其它欄位

//關於版本的table
node_revision:版本紀錄,資料的title欄位
field_revision_body:版本紀錄,資料的body欄位
field_revision_{欄位machine_name}:版本紀錄,資料的其它欄位

//關於cache的table
cache_field:node 欄位的cache 儲存

基本上,我只有半暴力法,
第一次匯入時,還是用migrate模組乖乖的匯入,
之後只有在大量更新時,再用暴力解決,直接存取資料庫:

//更新指定欄位的資料
db_update('field_data_'.$fieldName)
    ->fields(array($fieldName.'_value' => $fieldValue,))
    ->condition('entity_type', 'node')
    ->condition('entity_id', $nid)
    ->execute();
 
//更新指定欄位的版本資料
db_update('field_revision_'.$fieldName)
    ->fields(array($fieldName.'_value' => $fieldValue,))
    ->condition('entity_type', 'node')
    ->condition('entity_id', $nid)
    ->condition('revision_id', $vid)
    ->execute();

//清除node欄位的cache
cache_clear_all('field:node:' . $nid, 'cache_field');

題外話,“版本控制”又是另外一個問題,
若您整站沒有資料版本控制的話,
其實是可以裝Field SQL norevisions這個模組,
就不用理會revision相關的table了,
不過,要注意這模組說明中,有一段話:
WARNING: Once this module has been enabled there's no going back :)



0 意見: