Custom Models Tabelle updaten - ohne Datenverlust

Hallo Zusammen, ich suche nach einer Möglichkeit für ein bereits vorhandenes Custom Model die Tabellenfelder zu erweitern ohne das die vorhandenen Daten gelöscht werden. Dazu habe ich beim uninstall des Plugins das Entfernen der entsprechenden Schemata rausgenommen. Beim erneuten Installieren funktioniert der CREATE_TABLE Befehl nicht mehr, da die Tabelle - immer noch - existiert. Im SchemaTool selbst gibt es noch die updateSchema Methode, die verhält sich leider aber komplett anders als man es erwarten würde. Anstatt nur die übergebenen Klassen zu aktualisieren, vergleicht die Methode immer die komplette Datenbank gegen die übergebenen Klassen. Das führt leider dazu, das nach dem Update nur noch meine Tabellen da sind und alles andere weg ist.

[quote=“kuerbis”]Anstatt nur die übergebenen Klassen zu aktualisieren, vergleicht die Methode immer die komplette Datenbank gegen die übergebenen Klassen. Das führt leider dazu, das nach dem Update nur noch meine Tabellen da sind und alles andere weg ist.[/quote] Das durfte ich auch mal feststellen und habe mich ganz schön erschrocken… Du kannst in deine Update Methode einfach ein ALTER TABLE nutzen. Damit arbeite ich beim Erweitern von models - ohne Probleme. Viele Grüße

Das wäre natürlich eine Option, allerdings ist das ja nicht das was man sich vorstellt, wenn der Workflow über Doctrine eigentlich ein Anderer ist.

Ich habe ein Spezialisierung vom SchemaTool geschrieben, dass mit migrateClasses nur die Differenz der übergebenen PHP Klassen zum aktuellen Schema macht. Funktional macht es das Gleiche wie SchemaTool::updateSchema(), nur das es als Basis für den Vergleich nicht alle vorhanden Tabellen nimmt, sondern nur die, die für die übergebenen Klassen relevant sind. Das konkrete erstellen der SQL Statements übernimmt der Doctrine\DBAL\Schema\Comparator von Doctrine. Wenn diesbezüglich Fragen aufkommen, müsstest ihr in der Doctrine Dokumentation nachschauen. use Doctrine\ORM\EntityManager; use Doctrine\DBAL\Schema\Comparator; use Doctrine\DBAL\Schema\Schema; class SchemaTool extends \Doctrine\ORM\Tools\SchemaTool{ /\*\* \* Reference to the entity manager, it is already \* available in the parent class by not accessible here. \* \* @var \Doctrine\ORM\EntityManager \*/ protected $entityManager; /\*\* \* Constructor \* \* @param EntityManager $em \*/ public function \_\_construct(EntityManager $em) { parent::\_\_construct($em); $this-\>entityManager = $em; } /\*\* \* Migrates classes \* \* @param array $classes \* @param boolean $saveMode \* @throws \Doctrine\ORM\ORMException \*/ public function migrateClasses($classes, $saveMode = false) { $updateSql = $this-\>getMigrateClassesSql($classes, $saveMode); $conn = $this-\>entityManager-\>getConnection(); foreach ($updateSql as $sql) { $conn-\>executeQuery($sql); } } /\*\* \* Returns the sql statements that are needed to change the database. \* \* @param array $classes \* @param bool $saveMode \* @return array \* @throws \Doctrine\ORM\ORMException \*/ private function getMigrateClassesSql($classes, $saveMode = false) { $em = $this-\>entityManager; $conn = $em-\>getConnection(); $platform = $conn-\>getDatabasePlatform(); $fromSchema = $this-\>getExistingSchemaForClasses($classes); $toSchema = $this-\>getSchemaFromMetadata($classes); $comparator = new Comparator(); $schemaDiff = $comparator-\>compare($fromSchema, $toSchema); if ($saveMode) { return $schemaDiff-\>toSaveSql($platform); } return $schemaDiff-\>toSql($platform); } /\*\* \* Returns a Schema of the given classes from \* the existing schema. \* \* @param $classes \* @return Schema \*/ private function getExistingSchemaForClasses($classes) { $em = $this-\>entityManager; $schemaManager = $em-\>getConnection()-\>getSchemaManager(); $platform = $em-\>getConnection()-\>getDatabasePlatform(); $quoteStrategy = $this-\>entityManager-\>getConfiguration()-\>getQuoteStrategy(); $sequences = array(); if($platform-\>supportsSequences()) { $sequences = $this-\>listSequences(); } $tables = $schemaManager-\>listTables(); $tablesForClasses = array(); foreach ($tables as $table) { foreach ($classes as $class) { $tableName = $quoteStrategy-\>getTableName($class, $platform); if ($table-\>getName() == $tableName) { $tablesForClasses[] = $table; } } } return new Schema($tablesForClasses, $sequences, $schemaManager-\>createSchemaConfig()); } } In der Bootstrap.php beim in der install() Methode ruft man es wie folgt auf: $em = $this-\>Application()-\>Models(); $tool = new \SchemaTool($em); $classes = array( //list of custom model pathes ); $tool-\>migrateClasses($classes); Ich hoffe das hilft einigen bei der Plugin Entwicklung - mich nervt das immer, wenn ich jedes mal neue Testdaten brauche weil es Änderungen gibt.