Сущности Symfony не обновляются в базе данных после изменений

Мое приложение Symfony использует Doctrine для сохранения сущностей в mysql.

Сегодня я обновил свои объекты "Рекламодатель" и "Отчет", чтобы между ними были отношения - как предлагается в этом сообщении: При использовании EntityType для отображения выбора невозможно сохранить объект из формы Symfony

Когда я пытаюсь создать миграцию, он говорит, что база данных уже синхронизирована.

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

Пожалуйста, дайте мне знать, если у вас есть какие-либо предложения о том, как я могу обновить свою базу данных с моей обновленной схемой.

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Symfony Station Communiqué - 17 февраля 2023 г
Symfony Station Communiqué - 17 февраля 2023 г
Это коммюнике первоначально появилось на Symfony Station , вашем источнике передовых новостей Symfony, PHP и кибербезопасности.
Управление ответами api для исключений на Symfony с помощью KernelEvents
Управление ответами api для исключений на Symfony с помощью KernelEvents
Много раз при создании api нам нужно возвращать клиентам разные ответы в зависимости от возникшего исключения.
2
0
5 071
5
Перейти к ответу Данный вопрос помечен как решенный

Ответы 5

Попробуйте использовать правильную настройку аннотаций, может отсутствовать необходимая конфигурация, вы всегда можете попробовать проверить свою схему с помощью bin/console doctrine:schema:validate:

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

Также проверьте сущность Рекламодателя на наличие проблем, возможно, в ней отсутствует первичный ключ или что-то в этом роде.

Выполнение указанной вами команды приводит к следующему: [OK] Файлы сопоставления верны. [OK] Схема базы данных синхронизирована с файлами сопоставления.

Erich 12.02.2019 17:13

Я не понимаю, какими будут значения JoinColumn. Я использовал консоль Symfony, чтобы изменить сущность отчета, добавив рекламодателя в качестве типа отношения и настроив обратную сторону сущности рекламодателя, чтобы он мог получать отчеты. Поле рекламодателя_id, которое появляется в моих результатах SQL, является старым свойством, которого больше нет в моем коде сущности (но оно не было удалено из mysql). Новое свойство, которое консоль добавила в мой отчет, называется «рекламодатель» — это весь объект. Поэтому я не считаю, что включение adsr_id в мою аннотацию JoinColumn — это то, что необходимо.

Erich 12.02.2019 18:31

Может тогда я не понимаю в чем проблема. Но вы также должны изменить и таблицу рекламодателя, но вы не разместили ее здесь, поэтому я не могу судить, что не так, без кода сущности рекламодателя.

vytsci 12.02.2019 18:45

Теперь у вас есть однонаправленная ассоциация, вам нужна двунаправленная ассоциация. Если вы извлечете отчет, вы увидите прикрепленного к нему рекламодателя, но вы не сможете увидеть отчеты при извлечении рекламодателя. Пожалуйста, предоставьте нам ваш код рекламодателя.

vytsci 12.02.2019 18:46

Проблема была не в аннотациях или коде. Что-то пошло не так с миграциями — я думаю, потому что у меня уже было поле с именем «advertiser_id», которое я удалял одновременно с добавлением объекта рекламодателя в качестве свойства. Когда я делал это шаг за шагом — сначала удаляя свойство adsr_id, выполняя миграцию, а затем используя bin/console make:entity для добавления связанного объекта рекламодателя, все работало, как и ожидалось.

Erich 12.02.2019 20:40

Да Доктрина запуталась. Я рекомендую вам иметь контроль над именами столбцов, не оставляйте пустых аннотаций, потому что большинство пакетов и библиотек будут использовать змеиный регистр для имен своих столбцов, а ваш будет автоматически сгенерирован CamelCase, просто для более чистого управления кодом столбцов и имен таблиц.

vytsci 12.02.2019 21:15
Ответ принят как подходящий

Я считаю, что проблема заключалась в том, что ранее у меня было свойство под названием «advertiser_id» (int) в объекте отчета. И, возможно, я пытался изменить слишком много вещей одновременно, чтобы доктрина могла справиться. Раньше я пытался удалить рекламодатель_id при добавлении свойства отношения для рекламодателя.

Чтобы доктрина снова заработала, я удалил свойство рекламодателя из объекта Report вместе с геттерами и сеттерами. Я также удалил элементы обратного поиска из объекта Advertiser. Когда я попытался запустить миграцию, оказалось, что было несколько миграций, которые он пытался выполнить, и все они делали одно и то же: удаляли несуществующий внешний ключ. Поэтому я закомментировал все эти команды в файлах миграции и, наконец, смог выполнить миграцию. Я также удалил свойство adsr_id. Приложение снова работает.

Затем я попытался добавить свойство отношения «рекламодатель» обратно в отчет. На этот раз все сработало, как и ожидалось, и я смог выполнить миграцию. Поэтому я думаю, что проблема связана с тем, что мой объект уже имеет свойство adsr_id. Теперь, когда я добавил отношение рекламодателя к объекту отчета, я вижу, что доктрина добавила в таблицу столбец рекламодателя_id. Я подозреваю, что его присутствие ранее было причиной того, что все сломалось.

Спасибо за ответы! Рад, что он снова работает.

В случае, если это может помочь другим, для меня это был просто вопрос неправильного набора пространства имен в моем классе сущностей. Я продублировал объект из другого пакета и забыл обновить пространство имен.

mxlhz 13.10.2020 10:50

Как отношение много к одному, нормально, что вы являетесь столбцом рекламодателя базы данных, который хранит только ключ отчета как «ссылку» на него, поэтому Symfony не видит никаких изменений в вашей БД.

Возможно, вы также можете использовать:

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

чтобы увидеть изменения в вашей БД

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

применять изменения без использования миграций

У меня была такая же проблема, попробуйте очистить кеш с помощью:

symfony console cache:clear

Может кому пригодится, но при использовании аннотаций убедитесь, что блок комментариев соответствует формату DocBlock, в первой строке должно быть две звездочки: /** и ни одной звездочки /*

докблок

/**
*
*/

Многострочный комментарий PHP

/*
*
*
*/

Другие вопросы по теме