Мое приложение 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
Пожалуйста, дайте мне знать, если у вас есть какие-либо предложения о том, как я могу обновить свою базу данных с моей обновленной схемой.




Попробуйте использовать правильную настройку аннотаций, может отсутствовать необходимая конфигурация, вы всегда можете попробовать проверить свою схему с помощью bin/console doctrine:schema:validate:
/**
* @ManyToOne(targetEntity = "App\Entity\Advertiser", inversedBy = "reports")
* @JoinColumn(name = "advertiser_id", referencedColumnName = "id")
*/
private $advertiser;
Также проверьте сущность Рекламодателя на наличие проблем, возможно, в ней отсутствует первичный ключ или что-то в этом роде.
Я не понимаю, какими будут значения JoinColumn. Я использовал консоль Symfony, чтобы изменить сущность отчета, добавив рекламодателя в качестве типа отношения и настроив обратную сторону сущности рекламодателя, чтобы он мог получать отчеты. Поле рекламодателя_id, которое появляется в моих результатах SQL, является старым свойством, которого больше нет в моем коде сущности (но оно не было удалено из mysql). Новое свойство, которое консоль добавила в мой отчет, называется «рекламодатель» — это весь объект. Поэтому я не считаю, что включение adsr_id в мою аннотацию JoinColumn — это то, что необходимо.
Может тогда я не понимаю в чем проблема. Но вы также должны изменить и таблицу рекламодателя, но вы не разместили ее здесь, поэтому я не могу судить, что не так, без кода сущности рекламодателя.
Теперь у вас есть однонаправленная ассоциация, вам нужна двунаправленная ассоциация. Если вы извлечете отчет, вы увидите прикрепленного к нему рекламодателя, но вы не сможете увидеть отчеты при извлечении рекламодателя. Пожалуйста, предоставьте нам ваш код рекламодателя.
Проблема была не в аннотациях или коде. Что-то пошло не так с миграциями — я думаю, потому что у меня уже было поле с именем «advertiser_id», которое я удалял одновременно с добавлением объекта рекламодателя в качестве свойства. Когда я делал это шаг за шагом — сначала удаляя свойство adsr_id, выполняя миграцию, а затем используя bin/console make:entity для добавления связанного объекта рекламодателя, все работало, как и ожидалось.
Да Доктрина запуталась. Я рекомендую вам иметь контроль над именами столбцов, не оставляйте пустых аннотаций, потому что большинство пакетов и библиотек будут использовать змеиный регистр для имен своих столбцов, а ваш будет автоматически сгенерирован CamelCase, просто для более чистого управления кодом столбцов и имен таблиц.
Я считаю, что проблема заключалась в том, что ранее у меня было свойство под названием «advertiser_id» (int) в объекте отчета. И, возможно, я пытался изменить слишком много вещей одновременно, чтобы доктрина могла справиться. Раньше я пытался удалить рекламодатель_id при добавлении свойства отношения для рекламодателя.
Чтобы доктрина снова заработала, я удалил свойство рекламодателя из объекта Report вместе с геттерами и сеттерами. Я также удалил элементы обратного поиска из объекта Advertiser. Когда я попытался запустить миграцию, оказалось, что было несколько миграций, которые он пытался выполнить, и все они делали одно и то же: удаляли несуществующий внешний ключ. Поэтому я закомментировал все эти команды в файлах миграции и, наконец, смог выполнить миграцию. Я также удалил свойство adsr_id. Приложение снова работает.
Затем я попытался добавить свойство отношения «рекламодатель» обратно в отчет. На этот раз все сработало, как и ожидалось, и я смог выполнить миграцию. Поэтому я думаю, что проблема связана с тем, что мой объект уже имеет свойство adsr_id. Теперь, когда я добавил отношение рекламодателя к объекту отчета, я вижу, что доктрина добавила в таблицу столбец рекламодателя_id. Я подозреваю, что его присутствие ранее было причиной того, что все сломалось.
Спасибо за ответы! Рад, что он снова работает.
В случае, если это может помочь другим, для меня это был просто вопрос неправильного набора пространства имен в моем классе сущностей. Я продублировал объект из другого пакета и забыл обновить пространство имен.
Как отношение много к одному, нормально, что вы являетесь столбцом рекламодателя базы данных, который хранит только ключ отчета как «ссылку» на него, поэтому Symfony не видит никаких изменений в вашей БД.
Возможно, вы также можете использовать:
php bin/console doctrine:schema:update --dump-sql
чтобы увидеть изменения в вашей БД
php bin/console doctrine:schema:update --force
применять изменения без использования миграций
У меня была такая же проблема, попробуйте очистить кеш с помощью:
symfony console cache:clear
Может кому пригодится, но при использовании аннотаций убедитесь, что блок комментариев соответствует формату DocBlock, в первой строке должно быть две звездочки: /** и ни одной звездочки /*
докблок
/**
*
*/
Многострочный комментарий PHP
/*
*
*
*/
Выполнение указанной вами команды приводит к следующему: [OK] Файлы сопоставления верны. [OK] Схема базы данных синхронизирована с файлами сопоставления.