【发布时间】:2017-04-19 17:42:17
【问题描述】:
所以我已经完成了一堆 Doctrine2 迁移 (https://github.com/doctrine/migrations) 但我有一个关于我正在尝试做的新迁移的问题。
我一直在深入研究该库,发现$this->addSql() 用于构建要执行的 SQL 列表,然后稍后再执行。
我想做一些事情,我选择一些数据,遍历行,基于此插入新数据,然后删除我选择的数据。这很容易适用于 DBAL 库,但我想知道,我可以在迁移中安全地使用 protected $connection 吗?或者是因为它会在我的任何$this->addSql() SQL 被执行之前执行语句?此外,这似乎会破坏我在代码中看到的 dry-run 设置。有没有人有过这种迁移的经验?有什么最佳做法吗?
以下是我想做的迁移,但我不确定 Doctrine Migrations 是否支持:
public function up(Schema $schema)
{
// this up() migration is autogenerated, please modify it to your needs
$this->abortIf($this->connection->getDatabasePlatform()->getName() != "mysql");
$this->addSql("ALTER TABLE article_enclosures ADD is_scrape TINYINT(1) NOT NULL");
$this->addSql("ALTER TABLE images DROP FOREIGN KEY FK_E01FBE6AA536AAC7");
// now lets take all images with a scrape and convert the scrape to an enclosure
//
// Select all images where not scrape_id is null (join on article_image_scrape)
// for each image:
// insert into article_enclosures
// update image set enclosure_id = new ID
// delete from article_image_scrape where id...
//
// insert into article_enclosures select article_image_scrapes...
$sql = "SELECT i.id img_id, e.* FROM images i JOIN article_image_scrapes e ON i.scrape_id = e.id";
$stmt = $this->connection->prepare($sql);
$stmt->execute();
$scrapesToDelete = array();
while ($row = $stmt->fetch()) {
$scrapeArticle = $row['article_id'];
$scrapeOldId = $row['id'];
$scrapeUrl = $row['url'];
$scrapeExtension = $row['extension'];
$scrapeUrlHash = $row['url_hash'];
$imageId = $row['image_id'];
$this->connection->insert('article_enclosures', array(
'url' => $scrapeUrl,
'extension' => $scrapeExtension,
'url_hash' => $scrapeUrlHash
));
$scrapeNewId = $this->connection->lastInsertId();
$this->connection->update('images', array(
'enclosure_id' => $scrapeNewId,
'scrape_id' => null
), array(
'id' => $imageId
));
$scrapesToDelete[] = $scrapeOldId;
}
foreach ($scrapesToDelete as $id) {
$this->connection->delete('article_image_scrapes', array('id' => $id));
}
$this->addSql("INSERT INTO article_scrapes (article_id, url, extension, url_hash) "
."SELECT s.id, s.url, s.extension, s.url_hash"
."FROM article_image_scrapes s");
$this->addSql("DROP INDEX IDX_E01FBE6AA536AAC7 ON images");
$this->addSql("ALTER TABLE images DROP scrape_id, CHANGE enclosure_id enclosure_id INT NOT NULL");
}
【问题讨论】:
-
我决定在此之前和之后使用必要的
addSql调用进行单独的迁移,以便顺序正确。 -
你试过了吗?我觉得还可以
-
我想是的,但这是一年前的事了。我相信原来的问题仍然存在。也就是说,使用
->addSql()调用,这些调用将最后执行。dry-run仍将运行您的直接操作。所以它仍然看起来很老套(但我可能是错的,从来没有得到答案,而且我不再记得太多了)。 -
我遇到了一个类似的问题,最终使用了存储过程,因此可以将其添加为
addSql()语句的一部分。我使用sgalinski.de/typo3-agentur/technik/… 的第 4.1 节作为我需要做的基础的一部分
标签: php doctrine-orm database-migration