Frage

Wir verwenden Lehre Migrationen und es oft Probleme, wenn die Migration mehrere Aktionen enthält und einer von ihnen ausfällt.

Zum Beispiel, wenn es eine Migration ist die Zugabe von 5 Fremdschlüsseln und die fünfte von ihnen ausfällt, während Felder nicht von gleicher Länge sind, den Fehler mit den Feldern Festsetzung und regenerierende Migrationen tut nicht fix das ganze, während jetzt gibt es einen Fehler mit der Tatsache verbunden 4 des Schlüssels bereits vorhanden ist und nicht zulassen, dass die Migration erfolgreich ausgeführt werden.

Gibt es eine stabile Art und Weise Lehre Migrationen ohne solche offensichtlichen Probleme zu verwenden, wie erwähnt? Wir haben previosly .sql Dateien verwendet, die eigentlich nicht viel besser, aber ich bin mir ziemlich sicher, dass es die rechts Art und Weise der Datenbank für ein Lehre betriebenen Projekt Versionierung?

Erstellen von Migrationen basierend auf der Differenz zwischen den Modellen und Schema ist groß und ich möchte weiterhin diese Möglichkeit halten.

Danke

War es hilfreich?

Lösung

I Art, dies zu lösen, ist die Lösung nicht so schön, aber immer noch, ich denke, es wird auf andere Menschen nützlich sein. Ich verwende CLI in die Tat habe ich bereits die Datei macht jede Migration Update die Nummer in der Datenbank, ähnlich der in der Antwort der Timo getan, bevor diese Frage, aber das noch nicht sehr effektiv ist, aber es lohnt auf jeden Fall tun.

Was ich als nächstes Art löst Sachen getan haben, gehen Sie zu doctrine/lib/Doctrine/Migration/Builder.php Linie 531. Es ist die Definition der Standardklasse jeder Migration erstreckt. Da bin ich mit CLI und nicht einen Weg passieren Parameter an diesen Ort finden konnte ich nur Doctrine_Migration_Base in eine andere Klasse MY_Doctrine_Migration_Base ersetzt haben, die unten ist.

Wenn Sie nicht CLI verwenden würde ich sagen, Sie sollten versuchen, Optionen zu übergeben und nicht die Quelle ersetzen.

So die folgende Klasse erweitert Doctrine_Migration_Base und überschreibt eine Reihe von Methoden, um diejenigen, ob OK es der Überprüfung Änderungen vornehmen und dann Aufruf Mutter Methode, um sie zu tun. Es muss nicht alle Methoden decken derzeit nur die, die ich erlebt habe, als ich das geschrieben habe.

Jetzt kann jede Migration Lehre schafft sie meine Klasse, die zu verhindern, dass die Probleme ausgerichtet ist ich ursprünglich genannt.

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

Vorschläge, wie dies zu verbessern, sind willkommen.

Andere Tipps

Wenn Sie die Lehre-cli verwenden Sie Ihre eigenen Migrationsaufgabe schreiben kann, dass staut sich der Datenbank vor der Migration und Wiederherstellungen die Sicherung, wenn die Migration fehlschlägt. Ich schrieb etwas ähnliches für unsere symfony / Lehre Migrationen.

Wenn Sie Ihre Taskklasse im richtigen Verzeichnis cli die Lehre gelegt wird es in der Liste der verfügbaren Befehle angezeigt werden

Lehre Migrationen kann damit nicht umgehen. Leider sagen, dass wir alle diese Probleme haben, weil die Migration in einer Transaktion nicht ausgeführt hat.

Sie können dies verbessern, indem ein Plugin hinzufügen. Siehe: Blog-Post

Die andere Möglichkeit ist es, eine Datenbanksicherung zu tun, bevor die Migration und wenn etwas schief geht können Sie die Sicherung neu zu installieren. Sie können dies automatisieren, indem Sie einen Shell-Skript

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top