簡體   English   中英

Laravel將數據從一個表移動到另一個表並刪除數據來自的列?

[英]Laravel move data from one table to another and drop the column that the data came from?

我正在嘗試在Laravel遷移中執行以下過程:

創建一個名為client_log_partitions的新表。 (DONE)

$table->create();

$table->bigIncrements('id')->unique();
$table->bigInteger('client_log_id');
$table->mediumText('partition_data');

$table->timestamps();

  • 我已經有一個名為client_logs的表,其數據存儲在名為log_databigText()列中。
  • client_logs表中已存在的每一行需要每250 KB(或250,000個字符,因為它應該是單字節編碼)進行拆分,然后作為分區插入到新的client_log_partitions表中,並引用它所屬的client_logs條目。

我知道我可以使用$table->postExecute()實現這一點,我只是不知道我可能會這樣做。

將數據移動到新表后,我需要從client_logs刪除log_data列。

通常,我會用PHP腳本或類似的東西來做這件事。 但不幸的是,我在我無法做到的情況下運作。


我的問題是,這是否可以使用Laravel Migrations,如果是這樣,怎么樣?

編輯

雖然我不確定,因為我只是動態地掀起了它並且沒有測試過,這就是我想象的實現這個的SQL會是這樣的:

DROP PROCEDURE IF EXISTS PROCESS_LOG_DATA;
DROP PROCEDURE IF EXISTS PROCESS_LOG_ENTRIES;
DELIMITER ;;

## Procedure for processing a specific log entry
## and moving its data to the new table.
CREATE PROCEDURE PROCESS_LOG_DATA(log_id bigint, partition_size int)
BEGIN
    DECLARE n INT DEFAULT 0;
    DECLARE i INT DEFAULT 0;
    SELECT LENGTH(log_data)/partition_size FROM client_logs where id=log_id INTO n;
    SET i=0;
    WHILE i<n DO

      # Move the characters to the new table.
      INSERT INTO client_log_partitions 
          (client_log_id, partition_data)
      SELECT (id, LEFT(log_data, partition_size))
      FROM client_logs 
      WHERE id=log_id

      # Shift the characters off of the log_data
      UPDATE client_logs
      SET log_data = SUBSTR(
          log_data,
          partition_size,
          LENGTH(log_data) - partition_size
      ) where id=log_id;

      # Update the number of data partitions we've processed for this log entry
      SET i = i + 1;
    END WHILE;
End;
;;


## Procedure for processing all log entries
## and passing each one to the PROCESS_LOG_DATA procedure.
CREATE PROCEDURE PROCESS_LOG_ENTRIES(partition_size int)
BEGIN
    DECLARE n INT DEFAULT 0;
    DECLARE i INT DEFAULT 0;
    SELECT COUNT(*) FROM client_logs INTO n;
    SET i=0;
    WHILE i<n DO
        PROCESS_LOG_DATA(i, partition_size)
    END WHILE;
End;
;;

DELIMIETER ;

## Process the log entries.
CALL PROCESS_LOG_ENTRIES(250000);

您需要做的就是運行代碼來移動信息並在drop column調用之前重新關聯id。 這是因為up函數中的所有內容都是從上到下順序運行,而不是異步運行。 https://laravel.com/docs/5.8/migrations

您可以使用Eloquent和PHP來移動信息並對其進行更改。 這樣做可能比編寫查詢更容易。 這就是我工作過的公司移動數據然后改變表格的方式。 有時,由於SoX合規性愚蠢,我們不得不使用SQL腳本移動數據,但您不必擔心它聽起來像。

class DropClientLogsLogDataColumn extends Migration
{

    public function up()
    {
        // move data
        $this->moveData()

        Schema::table('client_logs', function (Blueprint $table) {
          // drop the log_data column
          $table->dropColumn('log_data');
        });
    }

    private function moveData()
    {
      // do whatever you need to do here 
      // more than likely you'll use eloquent or query builder
      // this is where you'd associate the id's
    }
}

改變你的新表遷移方法:

public function up()
{
    //Create the table
    Schema::create('your_table_name', function (Blueprint $table) {
        $table->bigIncrements('id')->unique();
        $table->bigInteger('client_log_id');
        $table->mediumText('partition_data');

        $table->timestamps();
    });

    //Copy column from last table to new table
    foreach(MyOldModel::all() as $item)
    {
        //now you can save old data into new table old data : $item -> log_data
        //other operation you want
        MyNewModel::create(array('partition_data' => $item -> log_data));//you can save other columns with adding array values
    }

    //Drop old table column
    Schema::table('client_logs', function (Blueprint $table) {
        $table->dropColumn('log_data');
    });
}

我想通過這種方式也可以遷移:rollback命令應該工作(撤消你的更改)!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM