教义迁移回落 [英] Doctrine migrations fallback

查看:157
本文介绍了教义迁移回落的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们正在使用原则迁移,当迁移包含多个操作并且其中一个失败时,通常会出现问题。



例如,如果有迁移添加5个外键,其中第5个失败,而字段长度不一致,修复了字段和重新生成迁移的错误,而不是修复整个事情,而现在有一个错误与事实4的密钥已经存在,不允许迁移成功运行。



有没有稳定的方式使用Doctrine迁移,没有提到这样明显的问题?我们以前已经使用了 .sql 文件,但实际上并没有太多的好处,但我确定有正确的数据库方式使用原则的项目的版本控制?



根据模型和模式之间的差异生成迁移是非常好的,我想进一步保持这种可能性。



谢谢

解决方案

我解决了这个问题,解决方案并不是那么好,但是我猜测将对其他人有用。我使用CLI确实我已经完成了文件,每个迁移更新数据库中的数字,类似于Timo的答案之前提出这个问题,但仍然不是很有效,但值得做的。



我已经做了下一个解决问题的东西,去
doctrine / lib / Doctrine / Migration / Builder.php line 531.默认类的定义每次迁移都会扩展。由于我使用的是CLI,并且找不到一种方法来传递参数到这个地方,我刚刚将 Doctrine_Migration_Base 替换到另一个类 MY_Doctrine_Migration_Base 以下。



如果您不使用CLI,我会说您应该尝试传递选项,而不是替换源。



所以下面的类扩展了 Doctrine_Migration_Base 并覆盖一堆方法,检查是否可以改变然后调用父方法来做它们。它不涵盖目前所有的方法,只是我写的时候遇到的那些方法。



现在,每个迁移原则创建扩展了我的课程,旨在防止我最初提到的问题。

 <?php 

class MY_Doctrine_Migration_Base扩展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'){
echoIndex $ indexName已经存在于表$ tableName中。
return;
}
}

父:: addIndex($ tableName,$ indexName,$ definition);
}

public function removeColumn($ tableName,$ columnName){
if($ this-> column_exists($ tableName,$ columnName)){
parent :: removeColumn($ tableName,$ columnName);
} else {
echo列$ columnName不存在于$ tableName中,不能丢弃\
}
}

public function createTable($ tableName,array $ fields = array(),array $ options = array()){
if($ this - > connection-> execute(SHOW TABLES LIKE'$ tableName') - > fetchAll(PDO :: FETCH_ASSOC)){
echo表$ tableName已存在,无法创建\ ;
} 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列$ columnName已存在于$ tableName中,无法添加\
}
}

私有函数column_exists($ tableName,$ columnName){
$ exception = FALSE;

尝试{//解析information_schema吮吸,因为如果我们有权访问,安全性会受到太大的伤害。这个跛脚shit还是比较好的
$ this-> connection-> execute(SELECT $ columnName FROM $ tableName) - > fetchAll(PDO :: FETCH_ASSOC);
} catch(异常$ exception){}
//如果有人知道如何检查列存在没有异常,没有信息SCHEMA请重写这个东西

return $ exception = == FALSE;
}
}

欢迎有关如何改进此事的建议。 p>

We're using doctrine migrations and there often are problems when the migration contains multiple actions and one of them fails.

For example, if there is a migration adding 5 foreign keys and the 5th of them fails while fields aren't of the same length, fixing the error with the fields and regenerating migrations does not fix the whole thing, while now there is an error connected with the fact 4 of the keys already exists and don't allow the migration to run successfully.

Is there a stable way to use Doctrine migrations without such obvious problems as mentioned? We've used .sql files previosly, which aren't much better actually, but I'm pretty sure there is the right way of database versioning for a Doctrine-using project?

Generating migrations based on the difference between models and schema is great and I'd like to keep this possibility furthermore.

Thanks

解决方案

I kind of solved this, the solution isn't all that nice, but still, I guess it will be useful to other people. I'm using CLI indeed I've already done the file making every migration update the number in the database, similar to the one in the Timo's answer before asking this question, but that still isn't very effective but worth doing anyway.

What I've done next kind of solves stuff, go to doctrine/lib/Doctrine/Migration/Builder.php line 531. There is the definition of the default class every migration will extends. Since I'm using CLI and could not find a way to pass parameters to this place I've just replaced Doctrine_Migration_Base to another class MY_Doctrine_Migration_Base which is below.

If you're not using CLI I'd say you should try to pass options and not replace source.

So the below class extends Doctrine_Migration_Base and overwrites a bunch of methods to the ones, checking whether it's OK to make changes and then calling parent method to do them. It doesn't cover all the methods currently, just the ones I've encountered when I wrote this.

Now every migration Doctrine creates extends my class which is aimed at preventing the problems I mentioned originally.

<?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;
    }
}

Suggestions on how to improve this are welcome.

这篇关于教义迁移回落的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆