Laravel 将数据从一个 table 移动到另一个 table 并删除数据来自的列?
Laravel move data from one table to another and drop the column that the data came from?
我正在尝试在 Laravel 迁移中执行以下过程:
创建一个名为 client_log_partitions
的新 table。 (完成)
$table->create();
$table->bigIncrements('id')->unique();
$table->bigInteger('client_log_id');
$table->mediumText('partition_data');
$table->timestamps();
- 我已经有一个名为
client_logs
的 table,数据存储在名为 log_data
的 bigText()
列中。
client_logs
table 中已经存在的每一行需要每 250 KB(或 250,000 个字符,因为它应该是单字节编码)拆分一次,然后插入到新的 client_log_partitions
table 作为分区,引用它所属的 client_logs
条目。
我知道我可以使用 $table->postExecute()
来实现这一点,我只是不知道我可以使用什么来做到这一点。
一旦数据移动到新的 table,我就需要从 client_logs
.
中删除 log_data
列
通常,我会使用 PHP 脚本或类似的东西来执行此操作。但不幸的是,我在无法做到的情况下工作。
我的问题是,使用 Laravel 迁移是否可行,如果可行,如何实现?
编辑:
虽然我不确定,因为我只是匆匆忙忙地做了这个,还没有测试过,这就是我想象的 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);
您需要做的就是运行您的代码来移动信息和re-associate删除列调用之前的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
}
}
将新的 table 迁移 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:rollback 命令也应该有效(用于撤消您的更改)!
我正在尝试在 Laravel 迁移中执行以下过程:
创建一个名为 client_log_partitions
的新 table。 (完成)
$table->create();
$table->bigIncrements('id')->unique();
$table->bigInteger('client_log_id');
$table->mediumText('partition_data');
$table->timestamps();
- 我已经有一个名为
client_logs
的 table,数据存储在名为log_data
的bigText()
列中。 client_logs
table 中已经存在的每一行需要每 250 KB(或 250,000 个字符,因为它应该是单字节编码)拆分一次,然后插入到新的client_log_partitions
table 作为分区,引用它所属的client_logs
条目。
我知道我可以使用 $table->postExecute()
来实现这一点,我只是不知道我可以使用什么来做到这一点。
一旦数据移动到新的 table,我就需要从 client_logs
.
log_data
列
通常,我会使用 PHP 脚本或类似的东西来执行此操作。但不幸的是,我在无法做到的情况下工作。
我的问题是,使用 Laravel 迁移是否可行,如果可行,如何实现?
编辑:
虽然我不确定,因为我只是匆匆忙忙地做了这个,还没有测试过,这就是我想象的 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);
您需要做的就是运行您的代码来移动信息和re-associate删除列调用之前的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
}
}
将新的 table 迁移 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:rollback 命令也应该有效(用于撤消您的更改)!