【问题标题】:How to avoid creating foreign key in Doctrine migration (bidirectional, with Single-table inheritance)?如何避免在 Doctrine 迁移中创建外键(双向,单表继承)?
【发布时间】:2020-03-01 18:08:49
【问题描述】:

有一个关于 Doctrine 的问题。 这是双向ManyToOne-OneToMany关联

class InternetPlan extends BaseProduct
...
    /**
     * @ORM\ManyToOne(targetEntity="App\Entity\PricingType", inversedBy="internetPlans")
     * @ORM\JoinColumn(name="pricing_type_id", referencedColumnName="id", nullable=true)
     * @JMS\Exclude()
     */
    private $pricingType;

父类是

/**
 * @ORM\Entity(repositoryClass="App\Repository\ProductsRepository")
 * @ORM\InheritanceType(value="SINGLE_TABLE")
 * @ORM\DiscriminatorColumn(name="type", type="string")
 * @ORM\DiscriminatorMap(
 *     {
 *     InternetPlan::type = "InternetPlan",
 *     TVPlan::type = "TVPlan",
 *     AdditionalServicePlan::type = "AdditionalServicePlan",
 *     Device::type = "Device"
 *     }
 *    )
 */
abstract class BaseProduct

反面是

class PricingType
...
    /**
     * @ORM\OneToMany(targetEntity="App\Entity\InternetPlan", mappedBy="pricingType")
     * @ORM\JoinColumn(nullable=true, onDelete="SET NULL")
     * @JMS\Type("object_ids")
     */
    private $internetPlans;

问题:当我执行 doctrine:migrations:diff 时,它想在父表基础产品中创建外键约束,忽略我的 JoinColumn(nullable=true)注释。

$this->addSql('ALTER TABLE base_product ADD CONSTRAINT FK_E74CBDC94B70279 FOREIGN KEY (pricing_type_id) REFERENCES pricing_type (id)');

当然,当我执行迁移时,会出现以下错误

 An exception occurred while executing 'ALTER TABLE base_product ADD CONSTRAINT FK_E74CBDC94B70279 FOREIGN KEY (pricing_type_id) REFERENCES pricing_type (id)':                                                                                      

  SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails (`taskman42`.`#sql-1_20`, CONSTRAINT `FK_E74CBDC94B70279` FOREIGN KEY (`pricing_type_id`) REFERENCES `pricing_type` (`id`)) 

所以我需要从每个新的迁移中手动删除这一行。

主要问题是:如何在每次新迁移中避免这条线?

【问题讨论】:

  • 就在FOREIGN KEY 行之前,您的迁移中应该有类似ALTER TABLE base_product ADD pricing_type_id INT DEFAULT NULL 的内容,对吧?
  • nullable=true 并不意味着该列不应该存在,也不意味着它不是外键。可为空的 true 仅意味着,通常可以允许不为实体设置关系,这仍然使得必须拥有该列并且非常非常非常建议拥有外键约束。当您正确设置该关系时,您可能可以避免这一行......这是一个关于该列在数据库中如何定义的问题,它应该如 Lucas Delobelle 所描述的那样。
  • 由于您的外键以前不存在,很可能您的数据库中存在违反约束的记录/行,可能是因为pricing_type_id 不存在作为pricing_type.id

标签: symfony doctrine-orm doctrine


【解决方案1】:

Jakumi 是对的,我最初忘记放入 JoinColumn(nullable=true) 的主要原因...之后,我创建了一个对象,它是 BaseProduct 的子类,因此该对象具有 price_type_id= 0 - 这就是外键约束如此丑陋的原因。

UPDATE base_product SET pricing_type_id=NULL WHERE pricing_type_id=0

这个 SQL 很有帮助

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-02-04
    • 1970-01-01
    • 2012-01-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多