更改后,Symfony 实体不会在数据库中更新

Posted

技术标签:

【中文标题】更改后,Symfony 实体不会在数据库中更新【英文标题】:Symfony entities are not updated in database after changes 【发布时间】:2019-02-12 15:53:21 【问题描述】:

我的 symfony 应用正在使用 Doctrine 在 mysql 中持久化实体。

今天我更新了我的实体“广告商”和“报告”,因此两者之间存在关系 - 正如这篇文章中所建议的那样:When using EntityType to show a select, can't save entity from Symfony form

当我尝试创建迁移时,它说数据库已经同步。

php bin/console make:migration

返回: [警告] 未检测到数据库更改。 数据库架构和应用程序映射信息已经同步。

但是,如果我查看报表的表格,我发现它仍然具有旧架构:

+---------------+------------+------+-----+---------+----------------+
| Field         | Type       | Null | Key | Default | Extra          |
+---------------+------------+------+-----+---------+----------------+
| id            | int(11)    | NO   | PRI | NULL    | auto_increment |
| advertiser_id | int(11)    | NO   | MUL | NULL    |                |
| start_date    | date       | NO   |     | NULL    |                |
| end_date      | date       | NO   |     | NULL    |                |
| deleted       | tinyint(1) | NO   |     | NULL    |                |
+---------------+------------+------+-----+---------+----------------+

即使我的实体现在看起来像这样:

class Report

    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer")
     */
    private $id;

    /**
     * @ORM\Column(type="date")
     */
    private $start_date;

    /**
     * @ORM\Column(type="date")
     */
    private $end_date;

    /**
     * @ORM\Column(type="boolean")
     */
    private $deleted;

    /**
     * @ORM\ManyToOne(targetEntity="App\Entity\Advertiser", inversedBy="reports")
     * @ORM\JoinColumn(nullable=false)
     */
    private $advertiser;

    public function getId(): ?int
    
        return $this->id;
    

    public function getStartDate(): ?\DateTimeInterface
    
        return $this->start_date;
    

    public function setStartDate(\DateTimeInterface $start_date): self
    
        $this->start_date = $start_date;

        return $this;
    

    public function getEndDate(): ?\DateTimeInterface
    
        return $this->end_date;
    

    public function setEndDate(\DateTimeInterface $end_date): self
    
        $this->end_date = $end_date;

        return $this;
    


    public function getDeleted(): ?bool
    
        return $this->deleted;
    

    public function setDeleted(bool $deleted): self
    
        $this->deleted = $deleted;

        return $this;
    

    public function getAdvertiser(): ?Advertiser
    
        return $this->advertiser;
    

    public function setAdvertiser(?Advertiser $advertiser): self
    
        $this->advertiser = $advertiser;

        return $this;
    

我一直在寻找解决方案并尝试了这些,但没有运气:

php bin/console doctrine:cache:clear-metadata
php bin/console doctrine:schema:update --force

如果您对如何使用更新后的架构更新数据库有任何建议,请告诉我。

【问题讨论】:

【参考方案1】:

作为 多对一 关系,您是数据库广告客户列仅将报告的键存储为“链接”是正常的,这就是 Symfony 看不到任何内容的原因数据库中的变化。

也许你也可以使用:

php bin/console doctrine:schema:update --dump-sql 

查看数据库中的变化

php bin/console doctrine:schema:update --force 

在不使用迁移的情况下应用更改

【讨论】:

【参考方案2】:

我有同样的问题,尝试清除缓存:

symfony console cache:clear

【讨论】:

【参考方案3】:

也许它对某人有用,但是在使用注释时确保注释块遵循 DocBlock 格式,第一行应该有两个星号:/** 而不是一个星号 /*

文档块

/**
*
*/

PHP 多行注释

/*
*
*
*/

【讨论】:

【参考方案4】:

尝试使用正确的注释设置可能会缺少所需的配置,您可以随时尝试使用bin/console doctrine:schema:validate 验证您的架构:

/**
 * @ManyToOne(targetEntity="App\Entity\Advertiser", inversedBy="reports")
 * @JoinColumn(name="advertiser_id", referencedColumnName="id")
 */
private $advertiser;

并检查 Advertiser 实体是否存在问题,可能它缺少主键或其他东西。

【讨论】:

运行您指定的命令,会产生: [OK] 映射文件是正确的。 [OK] 数据库架构与映射文件同步。 我很困惑 JoinColumn 的值是什么。我使用 Symfony 控制台来更改报告实体 - 将广告商添加为关系类型并在 Advertiser 实体上设置相反的内容,以便它可以获取报告。在我的 SQL 结果中出现的 ads_id 字段是我的实体代码中不再存在的旧属性(但尚未从 mysql 中删除)。控制台添加到我的报告中的新属性称为“广告商”——它是整个对象。所以我不认为在我的 JoinColumn 注释中包含 adser_id 是需要的。 也许我不明白那是什么问题。但是你还得修改adverter table,但是你没有贴在这里,所以没有advertisinger entity code我无法判断是什么问题。 你现在拥有的是单向关联,你需要的是双向关联。如果您检索报告,您将看到附加的广告商,但是当您检索广告商时您看不到报告。请向我们提供您的广告客户代码。 问题不在于注释或代码。迁移出了点问题 - 我相信是因为我已经有一个名为“advertiser_id”的字段,我在将广告客户对象添加为属性的同时删除了该字段。当我一步一步地执行它时 - 首先删除 adser_id 属性,迁移,然后使用 bin/console make:entity 添加相关的广告商对象,它按预期工作。【参考方案5】:

我认为问题在于我之前在报告对象上有一个名为“advertiser_id”(int) 的属性。可能我试图一次改变太多的东西,让教义无法管理。以前,我曾尝试在为广告客户添加关系属性时删除advertisingr_id。

为了让原则再次起作用,我从 Report 对象中删除了 adser 属性 - 以及 getter 和 setter。我还从 Advertiser 对象中删除了反向查找内容。当我尝试运行迁移时,它似乎试图运行多个迁移 - 都在做同样的事情:删除一个不存在的外键。所以我在迁移文件中注释掉了所有这些命令,最后能够让它迁移。我还删除了 advertiser_id 属性。该应用程序再次运行。

然后我尝试将“广告商”关系属性添加回报告中。这次它按预期工作,我能够迁移。所以我认为这个问题与我的对象已经有一个 ads_id 属性有关。现在我已将广告客户关系添加到 Report 对象,我看到该学说在表中添加了一个 ads_id 列。我怀疑它之前的存在是事情失败的原因。

感谢您的回复!很高兴它再次工作。

【讨论】:

如果它可以帮助其他人,对我来说这只是在我的实体类中设置了错误的命名空间。我从另一个包中复制了一个实体,忘记更新命名空间。

以上是关于更改后,Symfony 实体不会在数据库中更新的主要内容,如果未能解决你的问题,请参考以下文章

Symfony 4 - 避免更新数据库上没有给定的字段

Symfony4 学说单元测试:实体在缓存中有旧数据?

Symfony 4.4 安全性在登录后获取具有关系实体数据的用户

Symfony2 doctrine来自特定实体的更新架构

Symfony 2 从实体管理器获取实体的原始数据

从 symfony 4 中彻底删除实体