出于性能原因,我正在重构我们的实体设置。具体来说,我想切换一对一关系的拥有方。(主要是因为我一开始就设置错了...
问题:我想在实时系统上执行此操作
问题:最好的方法是什么:
- 不会丢失数据
- 使用学说迁移
从本质上讲,我想移动reference_id
字段及其所有数据,并将其移动到关系的另一端。
任何帮助将不胜感激。
下面是两个相关实体的一个示例
<?php
class Auction
{
/**
* @ORMOneToOne(targetEntity="AuctionParameter", mappedBy="auction", cascade={"persist", "remove"}, orphanRemoval=true)
*/
protected $auction_parameter;
}
class AuctionParameter
{
/**
* @ORMOneToOne(targetEntity="Auction", inversedBy="auction_parameter")
*/
protected $auction;
}
拍卖应保留参考 ID 而不是参数
从您的编辑中,我将假设reference_id
实际上auction_id
归表所有auction_parameter
首先,你应该制作一个数据库的副本(只有两个表就足够了)来测试我的脚本。我并不完美(远非如此),我可能犯了一个错误。
在执行脚本之前,必须在auction
表中添加新列。 我建议在下面的php脚本之外进行(例如通过PphMyAdmin)
ALTER TABLE `auction` ADD `auction_parameter_id` INT(11) NULL;
ALTER TABLE `auction_parameter` MODIFY `auction_id` INT(11) NULL;
然后在两个实体中切换拥有方。
拍卖实体
class Auction
{
/**
* @ORMOneToOne(targetEntity="AuctionParameter", inversedBy="auction", cascade={"persist", "remove"}, orphanRemoval=true)
*/
protected $auction_parameter;
}
拍卖参数实体
class AuctionParameter
{
/**
* @ORMOneToOne(targetEntity="Auction", mappedBy="auction_parameter")
*/
protected $auction;
}
保存它,但不要更新 SQL 架构,否则您将丢失所有内容。
现在这样做将确保新条目已经在正确的拥有方。
以防万一,您应该转储架构更改以确保Auction
表中的新列将被调用auction_parameter_id
如果没有,请调整上面的第一个 SQL 查询。
php bin/console doctrine:schema:update --dump-sql
现在auction
表已准备好欢迎拥有的密钥,运行此脚本应该可以解决问题:
$pdoLink=null;
$PARAM_HOST='localhost';
$PARAM_USER='db_user';
$PARAM_PASSWD='db_passwd';
$PARAM_DB='db_name';
$PARAM_CHARSET='utf8';
try {
$pdoLink=new PDO("mysql:host=$PARAM_HOST;dbname=$PARAM_DB;charset=$PARAM_CHARSET", $PARAM_USER, $PARAM_PASSWD);
$pdoLink->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch(Exception $e) {
echo 'Erreur : '.$e->getMessage().'<br />NР: '.$e->getCode();
exit();
}
$data=array();
$sth=$pdoLink->prepare(/** @lang MySQL */
"SELECT `auction_parameter`.`id` AS `owned`, `auction_parameter`.`auction_id` AS `owner`
FROM `auction_parameter`
WHERE `auction_parameter`.`auction_id` IS NOT NULL");
if($sth !== false && $sth->execute()) {
while($row=$sth->fetch(PDO::FETCH_ASSOC)) {
array_push($data, $row);
}
foreach($data as $datum) {
$sth=$pdoLink->prepare(/** @lang MySQL */
"UPDATE `auction`
SET `auction`.`auction_parameter_id`=:owned_side
WHERE `auction`.`id`=:owner_side");
$sth->bindParam(':owned_side', $datum['owned'], PDO::PARAM_INT);
$sth->bindParam(':owner_side', $datum['owner'], PDO::PARAM_INT);
if($sth !== false) {
$sth->execute();
}
}
}
$sth->closeCursor();
$pdoLink=null;
这应该可以满足您的需求。现在您所要做的就是使用原则更新 SQL 模式。(您可能需要手动删除foreign_key
和aucion_id
列,因为其中有数据)
php bin/console doctrine:schema:update --force