我有一个使用学说生成列的数据库。一列使用 type='array'。我想将其转换为 type='json'。我如何使用 MySQL 查询来做到这一点?
我尝试了以下 MySQL 命令:
ALTER TABLE user_parameter ADD ma_variable_tmp JSON NOT NULL;*/
UPDATE user_parameter SET ma_variable_tmp = CAST(pharmaciedevdata.user_parameter.value AS JSON) WHERE id>=1;
ALTER TABLE user_parameter DROP ma_variable;
ALTER TABLE user_parameter RENAME COLUMN ma_variable_tmp TO value;
我得到了这样的回应:
Error Code: 3141. Invalid JSON text in argument 1 to function cast_as_json: "Invalid value." at position 0. 0.000 sec
关注@A.L.想法,我最终得到了这段代码。该解决方案主要使用 PHP,并且可以使用 Doctrine Migration 来完成。
<?php
declare(strict_types=1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20230622200546 extends AbstractMigration
{
public function getDescription(): string
{
return '';
}
public function up(Schema $schema): void
{
$connection = $this->connection;
// Fetch the existing rows from the table
$rows = $connection->fetchAll('SELECT * FROM user_parameter');
// Iterate over each row
foreach ($rows as $row) {
$id = $row['id'];
$data = $row['value'];
//Unserialize data first since type array is serialize data
$encodedData=unserialize($data);
// Update the row with the new encoded data
$encodedData = json_encode($encodedData); // Encode the data using json_encode
$connection->executeUpdate('UPDATE user_parameter SET value = :encodedData WHERE id = :id', [
'encodedData' => $encodedData,
'id' => $id,
]);
}
}
public function down(Schema $schema): void
{}
}
这也是
down()
方法(json -> 数组)。 up()
是从@BePi答案复制的。
<?php
declare(strict_types=1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20230622200546 extends AbstractMigration
{
public function getDescription(): string
{
return '';
}
public function up(Schema $schema): void
{
$connection = $this->connection;
// Fetch the existing rows from the table
$rows = $connection->fetchAllAssociative('SELECT * FROM user_parameter');
// Iterate over each row
foreach ($rows as $row) {
$id = $row['id'];
$data = $row['value'];
//Unserialize data first since type array is serialize data
$encodedData=unserialize($data);
// Update the row with the new encoded data
$encodedData = json_encode($encodedData); // Encode the data using json_encode
$connection->executeUpdate('UPDATE user_parameter SET value = :encodedData WHERE id = :id', [
'encodedData' => $encodedData,
'id' => $id,
]);
}
}
public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE user_parameter CHANGE value value LONGTEXT DEFAULT NULL COMMENT \'(DC2Type:array)\''); // Set your column type!
// Change collation: needed to prevent errors: "Integrity constraint violation: 4025 CONSTRAINT ... failed for..."
$this->addSql('ALTER TABLE user_parameter MODIFY value LONGTEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci');
$connection = $this->connection;
// Migration from array to JSON
$rows = $connection->fetchAllAssociative('SELECT * FROM user_parameter ');
foreach ($rows as $row) {
$id = $row['id'];
$value = $row['value'];
// Decode data
$encodedData = json_decode($value);
// Serialize to array
$encodedData = serialize($encodedData); // Encode the data using json_encode
$connection->executeStatement('UPDATE user_parameter SET value = :encodedData WHERE id = :id', [
'encodedData' => $value,
'id' => $id,
]);
}
// Restore collation.
$this->addSql('ALTER TABLE user_parameter MODIFY value LONGTEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_bin'); // Set your column type!
}
}