当我尝试使用
重新加载我的灯具时php app / console doctrine:fixtures:load
我收到了这个错误:
SQLSTATE [23000]:完整性约束违规:1451无法删除或 更新父行:外键约束失败(
foo_db
。Book
,CONSTRAINTFK_C29271DD816C6140
FOREIGN KEY(author_id
)参考Author
(id
))
显示状态"> purging database"
时会显示错误。
这是我的代码:
class Book{
...
/**
* @ORM\ManyToOne(targetEntity="Author", inversedBy="books")
*/
private $author;
...
}
class Author{
...
/**
* @ORM\OneToMany(targetEntity="Book", mappedBy="author")
*/
private $books;
}
更多:我的老板有相同的代码,没有错误。
有什么想法吗?
sf 2.0.1(刚刚更新)/ ubuntu 10.10。
答案 0 :(得分:9)
如果我猜对了,你使用的是MySQL数据库。如果是,那么您将面临Doctrine2的doctrine-fixtures
库的当前版本的错误/问题。问题是他们使用TRUNCATE
命令清除当前数据库值,但此命令在删除MySQL中的外部关联时出现问题。
有关更多信息和解决方法,请参阅库的GitHub存储库中的this issue和this one。
在我的特定情况下,我从脚本运行此命令,所以为了使命令正常工作,我这样做:
php app/console doctrine:database:drop --force
php app/console doctrine:database:create
php app/console doctrine:schema:update --force
php app/console doctrine:fixtures:load --append
这样,清除是通过drop
命令完成的,并且追加具有与不附加相同的效果,因为加载灯具时数据库为空。
我必须承认我不知道为什么你的老板没有问题,也许他的数据库中没有与作者相关的书。
希望得到这个帮助。
的问候,
马特
答案 1 :(得分:1)
添加到composer.json新节脚本
"scripts": {
"load-fixtures": [
"bin/console doctrine:database:drop --if-exists --force",
"bin/console doctrine:database:create",
"bin/console doctrine:mi:m",
"bin/console doctrine:fixtures:load"
]
}
然后您可以运行composer install && composer load-fixtures
答案 2 :(得分:0)
我已经为Symfony 4创建了一个简单的Event Subscriber类。要解决自引用外键问题,只需将以下类添加到Symfony 4项目中即可。
此订户在每个Symfony CLI命令之前触发。如果命令的名称为doctrine:fixtures:load
,它将执行数据库清除,但首先执行SET FOREIGN_KEY_CHECKS = 0
。
这无需任何其他修改即可解决此问题。
use Doctrine\Common\DataFixtures\Purger\ORMPurger;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\Console\ConsoleEvents;
use Symfony\Component\Console\Event\ConsoleCommandEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class ConsoleCommandEventSubscriber implements EventSubscriberInterface
{
/**
* @var EntityManagerInterface
*/
private $entityManager;
public function __construct(EntityManagerInterface $entityManager)
{
$this->entityManager = $entityManager;
}
public static function getSubscribedEvents()
{
return [
ConsoleEvents::COMMAND => 'onCommand',
];
}
public function onCommand(ConsoleCommandEvent $event)
{
if ($event->getCommand()->getName() === 'doctrine:fixtures:load') {
$this->runCustomTruncate();
}
}
private function runCustomTruncate()
{
$connection = $this->entityManager->getConnection();
$connection->exec('SET FOREIGN_KEY_CHECKS = 0');
$purger = new ORMPurger($this->entityManager);
$purger->setPurgeMode(ORMPurger::PURGE_MODE_DELETE);
$purger->purge();
$connection->exec('SET FOREIGN_KEY_CHECKS = 1');
}
}