Обновление схемы Symfony2 Doctrine
Я создал базу данных на своей локальной машине. После переноса моего проекта на сервер я импортировал резервное копирование из локального (потому что у меня были некоторые важные данные).
Теперь, когда я пытаюсь обновить схему на своем сервере, он дает мне этот результат:
php app/console doctrine:schema:update --force
Updating database schema...
[Doctrine\DBAL\Exception\ForeignKeyConstraintViolationException]
An exception occurred while executing 'ALTER TABLE golf_course ADD CONSTRAINT FK_EC96E162F1503E2B FOREIGN KEY (golf_id) REFERENCES golf (id)':
SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails (`GolfFairway`.`#sql-3fae_7ccf1`, CONSTRAINT `FK_EC9
6E162F1503E2B` FOREIGN KEY (`golf_id`) REFERENCES `golf` (`id`))
[Doctrine\DBAL\Driver\PDOException]
SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails (`GolfFairway`.`#sql-3fae_7ccf1`, CONSTRAINT `FK_EC9
6E162F1503E2B` FOREIGN KEY (`golf_id`) REFERENCES `golf` (`id`))
[PDOException]
SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails (`GolfFairway`.`#sql-3fae_7ccf1`, CONSTRAINT `FK_EC9
6E162F1503E2B` FOREIGN KEY (`golf_id`) REFERENCES `golf` (`id`))
Почему это происходит? Есть ли решение?
Ответы
Ответ 1
Ваша проблема заключается в том, что вы хотите изменить таблицу с существующим ограничением. Я вижу два решения:
Если вы находитесь в dev, вы можете восстановить свою базу данных
doctrine:database:drop --force
doctrine:database:create
doctrine:schema:create
Если вы в производстве, это немного сложнее.
Одно из решений, которое я вижу, заключается в том, что вы можете создать команду для сохранения ваших данных, удаления данных в таблицах, которые вы хотите изменить, изменить вашу схему, перезагрузить данные после изменения таблицы. В зависимости от изменений он не должен занимать более 2-3 часов. Просто убедитесь, что у вас есть резервная копия, если ваша команда идет на юг.
Ответ 2
@maxian
Ответ Майкла Вильнева не совсем прав. В случае производственной среды или вида, вы просто можете отказаться от схемы и воссоздать ее.
Единственный способ выполнить его в вашей текущей схеме - это следующее:
- php app/console doctrine: schema: update --dump-sql. Скопируйте ouptut. Его прямые SQL-запросы для обновления вашей схемы
- подключить mysql к командной строке mysql или через клиент mysql
- Отключить проверку внешних ключей, вызвав этот запрос: "set foreign_key_checks = 0;"
- помещать запросы из doctrine: schema: update
- Включить проверку внешнего внешнего ключа с помощью:
"set foreign_key_checks = 1;"
Я не могу гарантировать, что вы не потеряете некоторые ключи, но не потеряете свои данные вообще.
Ответ 3
Обновление схемы с проверками внешнего ключа отключено
Если обновления схемы Doctrine не работают из-за ограничений внешнего ключа, вам просто нужно отключить проверки внешнего ключа для этого конкретного обновления.
Как однострочный, вы можете запустить:
mysql -e "set foreign_key_checks = 0; `app/console doctrine:schema:update --dump-sql`"
Это добавляет set foreign_key_checks = 0;
к выходу app/console doctrine:schema:update --dump-sql
, поэтому на самом деле вызывает то, что вызвала бы Doctrine, но с отключенными проверками внешнего ключа. Настройте вызов mysql
на ваши нужды.
Ваша схема обновляется, и в зависимости от ваших изменений данные не теряются.
Имейте в виду, что иногда порядок запросов важен, а Doctrine просто не упорядочивает их правильно. В этом случае вы должны правильно заказать запросы самостоятельно, а затем использовать этот упорядоченный список запросов.
Ответ 4
вам нужно добавить значение, связанное с полем в новой таблице.
Например: если у вас есть таблицы A и B, а B имеет ключ A (a_id), то вам нужно добавить поле в A с id = 1, а в таблице B a_id необходимо изменить на значение из Таблица - 1 в этом случае (сделайте это для всех полей).
После этого запустите:
доктрина php app/console: схема: обновление --force
С уважением
Ответ 5
Для меня это работало со следующей установкой (с двумя отношениями). Хитрость заключалась в том, чтобы не смешивать mappedBy
и inversedBy
.
/**
* @ORM\Entity
* @ORM\Table(name="user")
*/
class User extends BaseUser
{
/**
* @var Merchant
*
* @ORM\OneToOne(targetEntity="Merchant", mappedBy="user")
*/
protected $merchant;
/**
* @var Client
*
* @ORM\OneToOne(targetEntity="Client", mappedBy="user")
*/
protected $client;
}
/**
* @ORM\Table(name="merchant")
* @ORM\Entity
*/
class Merchant extends BaseEntity
{
/**
* @ORM\OneToOne(targetEntity="User", inversedBy="merchant")
*/
protected $user;
}
/**
* @ORM\Table(name="client")
* @ORM\Entity
*/
class Client extends BaseEntity
{
/**
* @ORM\OneToOne(targetEntity="User", inversedBy="client")
*/
protected $user;
}