我有点解决了这个问题,解决方案并不是那么好,但我想它仍然对其他人有用。我正在使用 CLI 确实我已经完成了文件,使每次迁移都会更新数据库中的数字,类似于在提出这个问题之前 Timo 的答案中的那个,但这仍然不是很有效,但无论如何都值得做。
我所做的下一种解决方法,转到
doctrine/lib/Doctrine/Migration/Builder.php
第 531 行。每个迁移都会扩展默认类的定义。由于我使用的是 CLI 并且找不到将参数传递到这个地方的方法,所以我刚刚替换为下面Doctrine_Migration_Base
的另一个类MY_Doctrine_Migration_Base
。
如果您不使用 CLI,我会说您应该尝试传递选项而不是替换源代码。
因此,下面的类扩展Doctrine_Migration_Base
并覆盖了一堆方法,检查是否可以进行更改,然后调用父方法进行更改。它不涵盖目前的所有方法,仅涵盖我在编写本文时遇到的那些。
现在,每个迁移 Doctrine 创建的都扩展了我的课程,旨在防止我最初提到的问题。
<?php
class MY_Doctrine_Migration_Base extends Doctrine_Migration_Base {
public function __construct() {
$this->connection = Doctrine_Manager::getInstance()->getCurrentConnection();
}
public function addIndex($tableName, $indexName, array $definition) {
foreach ($this->connection->execute("SHOW INDEXES IN $tableName")->fetchAll(PDO::FETCH_ASSOC) as $index) {
if ($index['Key_name'] === $indexName.'_idx') {
echo "Index $indexName already exists in table $tableName. Skipping\n";
return;
}
}
parent::addIndex($tableName, $indexName, $definition);
}
public function removeColumn($tableName, $columnName) {
if ($this->column_exists($tableName, $columnName)) {
parent::removeColumn($tableName, $columnName);
} else {
echo "Column $columnName doesn't exist in $tableName. Can't drop\n";
}
}
public function createTable($tableName, array $fields = array(), array $options = array()) {
if ($this->connection->execute("SHOW TABLES LIKE '$tableName'")->fetchAll(PDO::FETCH_ASSOC)) {
echo "Table $tableName already exists. Can't create\n";
} else {
parent::createTable($tableName, $fields, $options);
}
}
public function addColumn($tableName, $columnName, $type, $length = null, array $options = array()) {
if (! $this->column_exists($tableName, $columnName)) {
parent::addColumn($tableName, $columnName, $type, $length, $options);
} else {
echo "Column $columnName already exists in $tableName. Can't add\n";
}
}
private function column_exists($tableName, $columnName) {
$exception = FALSE;
try { //parsing information_schema sucks because security will hurt too bad if we have access to it. This lame shit is still better
$this->connection->execute("SELECT $columnName FROM $tableName")->fetchAll(PDO::FETCH_ASSOC);
} catch (Exception $exception) {}
//if someone knows how to check for column existence without exceptions AND WITHOUT INFORMATION SCHEMA please rewrite this stuff
return $exception === FALSE;
}
}
欢迎就如何改进这一点提出建议。