Domanda

Stiamo usando le migrazioni dottrina e ci sono spesso problemi quando la migrazione contiene azioni multiple e uno di loro viene a mancare.

Ad esempio, se v'è una migrazione aggiungendo 5 chiavi esterne e il 5 ° di loro non riesce, mentre i campi non sono della stessa lunghezza, fissando l'errore con i campi e rigenerante migrazioni non fix il tutto, mentre ora c'è un errore legato al fatto 4 delle chiavi esiste già e non consentono la migrazione per eseguire con successo.

C'è un modo stabile di utilizzare le migrazioni di Doctrine senza tali problemi evidenti come accennato? Abbiamo utilizzato i file .sql previosly, che non sono molto meglio in realtà, ma sono abbastanza sicuro che ci sia il destro modo di banca dati delle versioni per un progetto Doctrine utilizzano?

Generazione migrazioni sulla base della differenza tra i modelli e lo schema è grande e mi piacerebbe mantenere questa possibilità, inoltre,.

Grazie

È stato utile?

Soluzione

I tipi di risolto questo, la soluzione non è tutto ciò che bello, ma ancora, credo che possa essere utile ad altre persone. Sto usando CLI anzi ho già fatto il file rendendo ogni aggiornamento di migrazione il numero nel database, simile a quella nella risposta di Timo prima di chiedere a questa domanda, ma che ancora non è molto efficace, ma vale la pena fare in ogni caso.

Quello che ho fatto prossimo genere di cose risolve, andare a Linea doctrine/lib/Doctrine/Migration/Builder.php 531. V'è la definizione della classe predefinita ogni volontà di migrazione si estende. Dal momento che sto usando CLI e non sono riuscito a trovare un modo per passare parametri a questo luogo che ho appena sostituito Doctrine_Migration_Base ad un altro MY_Doctrine_Migration_Base classe che è al di sotto.

Se non si utilizza CLI direi si dovrebbe cercare di passare le opzioni e non sostituisce quest'ultima fonte.

Così il seguito di classe estende Doctrine_Migration_Base e sovrascrive una serie di metodi per quelli, verificare se è ok per apportare modifiche e quindi chiamando il metodo genitore per farle. Non copre tutti i metodi attualmente, solo quelli che ho incontrato quando ho scritto questo.

Ora ogni migrazione Dottrina crea estende la mia classe che mira a prevenire i problemi che ho citato in origine.

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

Suggerimenti su come migliorare questo sono i benvenuti.

Altri suggerimenti

Se si utilizza la dottrina-cli è possibile scrivere il proprio compito di migrazione che esegue il backup del database prima della migrazione e ripristini il backup se la migrazione non riesce. Ho scritto qualcosa di simile per i nostri symfony / migrazioni dottrina.

Se si mette la classe compito nella directory corretta del cli dottrina verrà visualizzato nella lista dei comandi disponibili

migrazioni dottrina non in grado di gestire questo. Mi dispiace dire che tutti abbiamo questi problemi, perché le migrazioni non aver corso una transazione.

È possibile migliorare questo con l'aggiunta di un plugin. Vedere: Blog-Post

L'altra possibilità è di fare un backup del database prima di migrare e se qualcosa va storto è possibile reinstallare il backup. È possibile automatizzare questo da uno script di shell

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top