在postUp()方法中删除列

时间:2011-04-06 10:33:54

标签: doctrine migration

是否可以删除迁移postUp()方法中的列,或仅用于数据操作?

1 个答案:

答案 0 :(得分:4)

我不知道您使用的是什么版本的Doctrine Migrations。但是,我在使用Doctrine Migrations 2.0时遇到了同样的问题,并开始深入研究代码。在查看如何构造版本时,似乎使用Schema对象在postUp()方法中进行更改不会生效。

然而,经过进一步考虑,这确实有道理。每个迁移版本都旨在修改数据库结构。这发生在每次迁移的up()和down()方法中。 postUp()似乎主要用于后结构更改清理(即操纵数据)。您在postUp()方法中进行的任何进一步的结构修改都应该在后续的迁移文件中进行。

例如,我试图创建一个新表,该表将保留前一个表中的两列。在将数据迁移到新表之后,我打算从上一表中删除这些列。代码如下:

class Version20110512223208 extends AbstractMigration
{
    protected $customerRepository;

    protected $evernoteRepository;

    public function up(Schema $schema)
    {
        $table = $schema->createTable('customer_evernote');
        $table->addOption('type', 'INNODB');
        $table->addOption('charset', 'utf8');
        $table->addOption('collate', 'utf8_unicode_ci');

        // Columns.
        $table->addColumn('customer_id', 'bigint', array(
            'length'    => 20,
            'notnull'   => true,
            'autoincrement' => false));
        $table->addColumn('integration_date', 'datetime', array('notnull' => true));
        $table->addColumn('oauth_token', 'string', array(
            'length'    => 255,
            'notnull'   => true));
        $table->addColumn('oauth_shard_id', 'string', array(
            'length'    => 4,
            'notnull'   => true,
            'fixed'     => true));

        $table->setPrimaryKey(array('customer_id'), 'pk_customer_id');
        $table->addForeignKeyConstraint($schema->getTable('customer'), array('customer_id'), array('id'));
    }

    public function down(Schema $schema)
    {
        $schema->dropTable('customer_evernote');
    }

    public function preUp(Schema $schema)
    {
        $this->addSql("ALTER TABLE `customer` ENGINE = INNODB");
    }

    public function postUp(Schema $schema)
    {
        $this->skipIf($this->version->isMigrated() !== true, 'postUp can only apply if migration completes.');

        // Copy the data from the customer table into the newly created customer_evernote table.
        $this->doctrine = \Zend_Registry::get('doctrine');
        $this->entityManager = $this->doctrine->getEntityManager();
        $this->customerRepository = $this->entityManager->getRepository('My\Entity\Customer');
        $this->evernoteRepository = $this->entityManager->getRepository('My\Entity\CustomerEvernote');
        $customers = $this->customerRepository->findAll();

        foreach ($customers as $customer)
        {
            $evernoteRecord = new \My\Entity\CustomerEvernote();
            $evernoteRecord->setCustomerId($customer->getId());
            $evernoteRecord->setCustomer($customer);
            $evernoteRecord->setOauthToken($customer->getEvernoteOauthToken());
            $evernoteRecord->setOauthShardId($customer->getEvernoteOauthShardId());
            $evernoteRecord->setIntegrationDate(new \DateTime("now"));

            $this->evernoteRepository->saveEvernote($evernoteRecord);
        }

        // Drop the columns from the existing customer table.
        $table = $schema->getTable('customer');
        $table->dropColumn('evernote_oauth_token');
        $table->dropColumn('evernote_oauth_shard_id');
    }

    public function preDown(Schema $schema)
    {
        // Create the existing columns in the customer table.
        $table = $schema->getTable('customer');
        $table->addColumn('evernote_oauth_token', 'string', array(
            'length'    => 255,
            'notnull'   => false));
        $table->addColumn('evernote_oauth_shard_id', 'string', array(
            'length'    => 4,
            'notnull'   => false,
            'fixed'     => true));

        // Copy the data to the customer table.
        $this->doctrine = \Zend_Registry::get('doctrine');
        $this->entityManager = $this->doctrine->getEntityManager();
        $this->customerRepository = $this->entityManager->getRepository('My\Entity\Customer');
        $this->evernoteRepository = $this->entityManager->getRepository('My\Entity\CustomerEvernote');

        $integrations = $this->evernoteRepository->findAll();

        foreach ($integrations as $integration)
        {
            $integration->getCustomer()->setEvernoteOauthToken($integration->getOauthToken());
            $integration->getCustomer()->setEvernoteOauthShardId($integration->getOauthShardId());

            $this->customerRepository->saveCustomer($integration->getCustomer());
        }
    }
}

实际上,如果我将postUp()末尾的代码移动到新版本的up(),将preDown()开头的代码移动到新版本的down()方法,我得到了与上述类相同的结果,仅在两个单独的步骤中执行。通过这种方法,我保证在我的上下方法中发生严格的结构修改。