Laravel переместить данные из одной таблицы в другую и отбросить столбец, из которого получены данные? - PullRequest
0 голосов
/ 25 мая 2019

Я пытаюсь выполнить следующий процесс в миграции Laravel:

Создать новую таблицу с именем client_log_partitions.(СОВЕРШЕНО)

$table->create();

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

$table->timestamps();

  • У меня уже есть таблица с именем client_logs с данными, хранящимися в столбце bigText() с именем log_data.
  • Каждая строка, которая уже существует в таблице client_logs, должна быть разделена каждые 250 КБ (или 250 000 символов, поскольку она должна быть однобайтовой), а затем вставлена ​​в новую таблицу client_log_partitions как разделы, сссылка на запись client_logs, к которой она принадлежит.

Я знаю, что смогу достичь этого с помощью $table->postExecute(), я просто не знаю, что я мог бы использовать для этого.

Как только данные будут перемещены вВ новой таблице мне нужно удалить столбец log_data из client_logs.

Обычно я делаю это с помощью 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);

Ответы [ 2 ]

0 голосов
/ 25 мая 2019

Измените новую миграцию таблицы up метод на:

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');
    });
}

Я думаю, таким образом также migrate: откат команда должна работать (для отмены вашейизменения)!

0 голосов
/ 25 мая 2019

Все, что вам нужно сделать, это запустить свой код, чтобы переместить информацию и повторно связать идентификаторы перед вызовом отбрасываемого столбца. Это потому, что все в функции 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
    }
}
...