Laravel перемещает данные из одной таблицы в другую и удаляет столбец, из которого были получены данные?

Я пытаюсь выполнить следующий процесс миграции 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);

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
4
0
6 496
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Все, что вам нужно сделать, это запустить свой код, чтобы переместить информацию и повторно связать идентификаторы перед вызовом столбца удаления. Это связано с тем, что все в функции up выполняется последовательно, сверху вниз, а не асинхронно. https://laravel.com/docs/5.8/миграции

Вы можете использовать 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
    }
}

Прямо сейчас я пытаюсь понять, как я буду перемещать данные по 250 символов за раз в новую таблицу, используя SQL, построитель запросов или красноречивый.

Nathan F. 25.05.2019 17:37

Измените новый метод переноса таблиц вверх на:

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

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

Мне нужно разделить данные, поступающие из таблицы client_logs, каждые 250 символов, прежде чем вставлять их в новую таблицу. Однако я не могу сделать это с помощью модели, поскольку данные, хранящиеся в старой таблице, слишком велики, чтобы загрузить их все сразу в PHP (отсюда и необходимость этого разделения в первую очередь)

Nathan F. 25.05.2019 17:49

чтобы миграция: откат работал, вам нужно сначала добавить метод down() и отменить процесс там... в любом случае, получить MyOldModel::all(), а затем зациклиться на нем и вызвать однократное создание в приложении очень, очень ресурсоемко для больших сумм данных, особенно в PHP - вы, вероятно, убьете память :), и я бы посоветовал вам нет использовать ::all()-подобные геттеры для данных с неопределенным/неизвестным размером.

jave.web 12.11.2019 03:39

связанный ответ о данных миграции в Laravel: stackoverflow.com/a/23506744/470749

Ryan 12.12.2019 22:33

Другие вопросы по теме