gpt4 book ai didi

php - 使用 DBAL 代替 $this->addSql 的 Doctrine2 迁移

转载 作者:IT王子 更新时间:2023-10-29 00:11:10 24 4
gpt4 key购买 nike

所以我已经完成了一系列 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");
}

最佳答案

你可以像这样使用$connection

$result = $this->connection->fetchAssoc('SELECT id, name FROM table1 WHERE id = 1');
$this->abortIf(!$result, 'row with id not found');
$this->abortIf($result['name'] != 'jo', 'id 1 is not jo');
// etc..

您应该只读取数据库而不是使用连接进行更新/删除,这样就不会破坏试运行选项。

在您的示例中,您应该进行两次迁移。第一个会做两个alter table。第二个将执行“带有抓取的图像并将抓取转换为外壳”例程。如果出现问题,使用多重迁移更容易恢复它们。

关于php - 使用 DBAL 代替 $this->addSql 的 Doctrine2 迁移,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10355678/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com