ノードリビジョンを削除する方法


7

移行の時間を節約するために、Drupal 7にアップグレードする前にすべてのノードリビジョンを削除する必要があります。それを行う方法はありますか?


申し訳ありません:私の最初の答えは不完全でした。ノードリビジョンを削除することを他のモジュールに通知する必要があります。そうしないと、サードパーティのモジュールによって処理されるデータベーステーブルにリビジョンデータが残ってしまいます。移行中、サードパーティのモジュールが古い情報を削除する可能性がありますが、不要なデータを削除するために既存のリビジョンをチェックすることはないと思います。多くのノードがあるDrupalサイトでは、時間がかかります。
kiamlaluno

回答:


12

次のコードを使用できます。

db_query('DELETE FROM {node_revisions} nr WHERE nr.vid NOT IN (SELECT n.vid FROM {node} n)');

すべてのリビジョンを削除したくない場合:現在のリビジョン以外をすべて削除したい場合。

リビジョンに関する情報を保存するモジュールはリビジョンが削除されることを通知されないため、そのクエリのみを実行すると、削除されたリビジョンに関するデータが他のデータベーステーブルに残ります。たとえば、ノードフィールドに関する情報を独自のデータベーステーブルに保存するCCKモジュールについて考えています。リビジョンが削除されると、CCKモジュールは次のコードを実行します。

/**
 * Implementation of hook_nodeapi 'delete_revision' op.
 *
 * Delete node type fields for a revision.
 */
function content_delete_revision(&$node) {
  _content_field_invoke('delete revision', $node);
  _content_field_invoke_default('delete revision', $node);
  cache_clear_all('content:'. $node->nid .':'. $node->vid, content_cache_tablename());
}

より完全なコードは次のコードのようになります。

$query = db_query('SELECT nr.nid, nr.vid FROM {node_revisions} nr WHERE nr.vid NOT IN (SELECT n.vid FROM {node} n)');

while ($revision = db_fetch_object($query)) {
  if ($node = node_load($revision->nid, $revision->vid)) {
    node_invoke_nodeapi($node, 'delete revision');
  }
}

db_query('DELETE FROM {node_revisions} nr WHERE nr.vid NOT IN (SELECT n.vid FROM {node} n)');

node_revision_delete_confirm_submit()のコードを見ると、他に実行する必要があるものはありません。

私が書いた新しいコードは、ノードの数とリビジョンによっては、実行に時間がかかる場合があります。つまり、コードを実行する必要があります。

  1. hook_cron()の実装では
  2. バッチ操作として
  3. Drupalをブートストラップし、実行時間を増やすPHPファイル内 @set_time_limit(240)
  4. Drushあり

コードは移行にのみ必要であることを考えると、この非常に特殊なケースで必要なモジュールを作成する必要がある最初の2つのオプションは避けます。より多くのサイトがあり、それらすべてが同じコードを実行する必要がある場合、オプション3は常に可能であり、それはcron.phpを使用してDrupalから行われます
オプション4について、私は最初に、Drushがこの場合に役立つ可能性があるコマンドをまだ持っていないことを確認します。厳密に必要でない場合、私はホイールを再発明しません。また、Drush Shell Scriptsの記述方法も確認します。


ありがとうKiamlaluno ...ええ私は現在のリビジョンを保持したいと思います。
user8012 2012

1
これによりフィールド値のリビジョンも転送されなくなるかどうか誰かが知っていますか?私はそれがそうなると思いますが、好奇心だけです。
ジョナサンエルモア

@JohnathanElmore回答を更新しました。
kiamlaluno

:)それは素晴らしいです。これはサーバーに大きな負荷がかかると思いますが、一部のini_set( 'memory_limit'、 '128M'); および/またはini_set( 'max_execution_time'、1000); これらの種類の問題を軽減します。
Johnathan Elmore

3
適切なサブクエリは(SELECT n.vid FROM {node} n)です。そうしないと、不正な列名に関するSQLエラーが発生します。
mpdonadio

1

データベースに500,000以上の古いリビジョンがあるウェブサイトがありました。http://drupal.org/project/revision_deletionと呼ばれる少数のリビジョンをノックアウトするための素晴らしいモジュールがあり ます。ただし、大きなセットをすばやく削除するために、このスクリプトを作成しました。

一般的なアイデアは、特定の日付より古いすべてのリビジョンを削除してから、各CCKテーブルに対して同じことを行うことです。どの日付制限を選択しても、現在のリビジョンは削除されません。

警告:テーブルの命名規則について想定しています-バックアップでのみ使用してください

<?php
// Note - this is for Drupal 6.x
function remove_revisions() {

  // Set limit for revision age
  $days_ago = 30;

  // delete all revisions from node_revisions
  $limit = time() - (60*60*24*$days_ago);
  $sql = "DELETE FROM node_revisions WHERE timestamp < $limit AND vid NOT IN (SELECT vid FROM node)";
  db_query($sql);

  $rows = db_affected_rows();
  drupal_set_message("$rows revisions deleted -- node_revisions");

  $table_types = array('content_field_%%', 'content_type_%%');

  // remove orphaned data from CCK content tables
  foreach($table_types as $table_type) {
    $result= db_query("SHOW TABLES LIKE '$table_type'");
    while ($row = db_fetch_array($result)) {
      $table = current($row);
      $sql = "DELETE FROM $table WHERE vid NOT IN (SELECT vid FROM node_revisions)";
      db_query($sql);
      $rows = db_affected_rows();
      drupal_set_message("$rows revisions deleted -- $table");
    }
  }
}
?>

ソース:http : //fivepaths.com/drupal-revision-removal-and-database-cleanup-by-brute-force



0

このコードは、ノードリビジョンとすべてのCCKリビジョンを処理します。リビジョンを保存する他の可能なモジュールについては認識していませんが、高速であり、cron、バッチ、実行時間制限、またはDrushについて考えることを避けます。また、今日から何日後までリビジョンを削除したくないかなど、日数制限の設定もあります。コードをいくつかのモジュール内に配置し、hook_menuを追加する必要があります。私にとってはうまくいきました。

http://fivepaths.com/drupal-revision-removal-and-database-cleanup-by-brute-force

2015年8月3日を編集:おっと、ページが消えています。誰かが望めば、これを掘り下げることができます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.