在迁移文件中使用EntityManager

时间:2013-10-21 19:04:29

标签: symfony doctrine-orm migration

我有这段代码,但不起作用:

<?php

namespace Application\Migrations;

use Doctrine\DBAL\Migrations\AbstractMigration,
    Doctrine\DBAL\Schema\Schema;

/**
 * Auto-generated Migration: Please modify to your need!
 */
class Version20131021150555 extends AbstractMigration
{

    public function up(Schema $schema)
    {
        // this up() migration is auto-generated, please modify it to your needs
        $this->abortIf($this->connection->getDatabasePlatform()->getName() != "mysql", "Migration can only be executed safely on 'mysql'.");

        $this->addSql("ALTER TABLE person ADD tellphone LONGTEXT DEFAULT NULL");

        $em = $em = $this->getDoctrine()->getEntityManager();
        $persons = $em->getRepository('AutogestionBundle:Person')->fetchAll();

        foreach($persons as $person){
            $person->setTellPhone($person->getCellPhone());
            $em->persist($person);                                                                            
        }
        $em->flush(); 
    }

    public function down(Schema $schema)
    {
        // this down() migration is auto-generated, please modify it to your needs
        $this->abortIf($this->connection->getDatabasePlatform()->getName() != "mysql", "Migration can only be executed safely on 'mysql'.");

        $this->addSql("ALTER TABLE person DROP tellphone");
    }
}

我已经在手机中添加了一个新的字段发送消息。

由于

3 个答案:

答案 0 :(得分:46)

这可能是较旧的帖子,但同时问题已解决,实际上是当前文档的一部分。

请参阅http://symfony.com/doc/current/bundles/DoctrineMigrationsBundle/index.html#container-aware-migrations

// ...
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\ContainerAwareTrait;

class Version20130326212938 extends AbstractMigration implements ContainerAwareInterface
{
    use ContainerAwareTrait;

    public function up(Schema $schema)
    {
        // ... migration content
    }

    public function postUp(Schema $schema)
    {
        $em = $this->container->get('doctrine.orm.entity_manager');
        // ... update the entities
    }
}

答案 1 :(得分:7)

我确实意识到这有点陈旧,但要了解我的错误,并且:

甚至都不要考虑在迁移中使用实体管理器

尤其是您要使用它的方式-获取实体存储库。

这就是为什么。

想象一下您有一个DogEntity字段为$name的情况。现在,您将基于该实体生成一个迁移文件(假设其为Version1)。到目前为止一切顺利。

接下来,您要使用实体管理器来获取该DogEntity的存储库,更新记录,并对该实体进行任何操作。这样就可以了,而且还可以(假设此迁移文件的名称为Version2)。

现在,您将$color字段添加到DogEntity,再次生成迁移(这是一个名为Version3的文件)。没关系...

...直到开始尝试从开始运行所有迁移。在那一刻,将在Version2文件的迁移过程中引发错误。为什么?因为实体管理器在数据库中寻找color字段。但是稍后会在Version3文件中创建该字段。

TLDR:实体管理器查找您当前拥有的列,这些列从一开始就运行迁移会导致问题。

答案 2 :(得分:6)

您必须使用postUp()方法调用您的修改 - addSql() - 语句将在up()方法完成后执行,因此您的新行(即tellphone)在up()方法!