db_schema.xml
5 Fehler, die Entwickler vermeiden sollten
Declarative Schema ersetzt alte InstallScripts, aber nur wenn Tabellen, Constraints, Indexes und Patches sauber getrennt werden. Diese fünf Fehler verursachen die meisten Probleme in Magento-Projekten.
Inhaltsverzeichnis
- 1. Warum db_schema.xml wichtig ist
- 2. Fehler 1: InstallScripts weiterverwenden
- 3. Fehler 2: Datenänderungen in db_schema.xml erzwingen
- 4. Fehler 3: Constraints und Indexes unsauber definieren
- 5. Fehler 4: Whitelist ignorieren
- 6. Fehler 5: Änderungen ohne Upgrade-Strategie
- 7. Vergleich: db_schema.xml vs. Patch
- 8. Magento 2 Unterstützung
- 9. Zusammenfassung
- 10. FAQ
1. Warum db_schema.xml wichtig ist
db_schema.xml Magento 2 ist der zentrale Mechanismus für deklaratives Datenbankschema. Statt Tabellen über alte Install- oder Upgrade-Scripts manuell zu erzeugen, beschreibst du den gewünschten Zielzustand der Datenbank in XML. Magento vergleicht diesen Zielzustand mit der aktuellen Datenbank und berechnet daraus die nötigen Änderungen. Das macht Schema-Änderungen nachvollziehbarer, reproduzierbarer und besser wartbar.
Der Vorteil ist groß, aber nur wenn die Datei sauber eingesetzt wird. db_schema.xml beschreibt Struktur: Tabellen, Spalten, Indexes und Constraints. Sie ist nicht für Datenmigration, Default-Datensätze, komplexe Umwandlungen oder Business-Logik gedacht. Genau an dieser Grenze entstehen viele Fehler. Entwickler schreiben zu viel in das Schema, vergessen Patches oder ändern bestehende Tabellen ohne klare Upgrade-Strategie.
Wer mit Magento 2.4.8 arbeitet, sollte deklaratives Schema als Standard verwenden. Neue Module brauchen keine InstallScripts mehr. Wenn ein Modul eigene Tabellen benötigt, gehört die Definition in app/code/Vendor/Module/etc/db_schema.xml. Datenänderungen gehören in Data Patches, komplexe Strukturmigrationen in Schema Patches oder bewusst geplante Upgrade-Schritte.
In Teams ist außerdem wichtig, dass Schema-Änderungen wie normaler Anwendungscode reviewed werden. Eine neue Spalte wirkt harmlos, kann aber Index-Größe, Importgeschwindigkeit, API-Antworten und Deployment-Zeit beeinflussen. Eine neue Foreign-Key-Beziehung kann Datenqualität verbessern, aber auch Löschprozesse blockieren. Eine zu breite Tabelle kann später Indexer und Exporte verlangsamen. Deshalb sollte jede Änderung an db_schema.xml Magento 2 mit der Frage beginnen, welche Datenmenge heute existiert und welche Datenmenge in zwölf Monaten realistisch ist.
<?xml version="1.0"?>
<schema xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:framework:Setup/Declaration/Schema/etc/schema.xsd">
<table name="mironsoft_example" resource="default" engine="innodb" comment="Mironsoft Example">
<column xsi:type="int" name="entity_id" unsigned="true" nullable="false" identity="true"
comment="Entity ID"/>
<column xsi:type="varchar" name="title" nullable="false" length="255" comment="Title"/>
<column xsi:type="timestamp" name="created_at" nullable="false" default="CURRENT_TIMESTAMP"
comment="Created At"/>
<constraint xsi:type="primary" referenceId="PRIMARY">
<column name="entity_id"/>
</constraint>
</table>
</schema>
2. Fehler 1: InstallScripts weiterverwenden
Der erste Fehler ist der häufigste: Entwickler erstellen ein neues Modul und schreiben trotzdem InstallSchema oder UpgradeSchema. Das ist in modernen Magento-Projekten nicht mehr der richtige Weg. Wenn du eine neue Tabelle brauchst, gehört sie in db_schema.xml Magento 2. Alte Setup-Scripts machen Upgrades schwerer vorhersehbar und führen schneller zu unterschiedlichen Datenbankzuständen zwischen Entwicklung, Staging und Produktion.
Das bedeutet nicht, dass alte Module sofort komplett umgebaut werden müssen. Legacy-Code muss man kontrolliert migrieren. Für neue Module ist die Regel aber klar: kein InstallScript für Tabellenstruktur. Deklaratives Schema ist der Standard. Es beschreibt den Zielzustand, und Magento kümmert sich um die Differenz.
Ein praktischer Nebeneffekt: Neue Entwickler verstehen ein Modul schneller, wenn die Tabellenstruktur an einer festen Stelle liegt. Sie müssen nicht mehrere historische Upgrade-Scripts lesen und gedanklich ausführen, um den aktuellen Zustand zu rekonstruieren. Gerade bei langfristig gepflegten Magento-Shops spart das viel Zeit. Das Schema wird zur Dokumentation des aktuellen Datenmodells.
<?php
declare(strict_types=1);
namespace Mironsoft\Example\Setup;
use Magento\Framework\Setup\InstallSchemaInterface;
/**
* Deprecated approach for new Magento modules.
*/
class InstallSchema implements InstallSchemaInterface
{
// Do not create new tables this way in new Magento 2 modules.
}
Die korrekte Variante ist eine saubere db_schema.xml. Dadurch sieht jeder Entwickler sofort, welche Tabellen und Spalten das Modul erwartet. Zusätzlich kann Magento Schema-Differenzen systematisch erkennen.
3. Fehler 2: Datenänderungen in db_schema.xml erzwingen
Der zweite Fehler ist subtiler: db_schema.xml wird für Dinge genutzt, die keine Struktur sind. Ein Beispiel ist das Einfügen von Konfigurationswerten, initialen Datensätzen oder komplexen Umwandlungen. Dafür ist db_schema.xml Magento 2 nicht gedacht. Sie beschreibt Tabellen und Spalten, nicht fachliche Daten.
Wenn dein Modul Default-Konfiguration braucht, nutzt du config.xml. Wenn es initiale Datensätze oder Migrationen braucht, nutzt du Data Patches. Wenn eine einmalige Strukturänderung nicht deklarativ sauber abbildbar ist, kommt ein Schema Patch infrage. Diese Trennung ist wichtig, weil Schema und Daten unterschiedliche Lebenszyklen haben.
<?php
declare(strict_types=1);
namespace Mironsoft\Example\Setup\Patch\Data;
use Magento\Framework\Setup\ModuleDataSetupInterface;
use Magento\Framework\Setup\Patch\DataPatchInterface;
/**
* Inserts initial example data for the module.
*/
final class AddInitialExampleData implements DataPatchInterface
{
public function __construct(
private readonly ModuleDataSetupInterface $moduleDataSetup
) {}
public function apply(): self
{
$connection = $this->moduleDataSetup->getConnection();
$connection->insertOnDuplicate(
$this->moduleDataSetup->getTable('mironsoft_example'),
[
'entity_id' => 1,
'title' => 'Initial Example'
],
['title']
);
return $this;
}
public static function getDependencies(): array
{
return [];
}
public function getAliases(): array
{
return [];
}
}
4. Fehler 3: Constraints und Indexes unsauber definieren
Der dritte Fehler betrifft Constraints und Indexes. Viele Tabellen funktionieren zuerst auch ohne saubere Fremdschlüssel oder Indexes. Später entstehen dann Performance-Probleme oder Dateninkonsistenzen. Eine gute db_schema.xml Magento 2 definiert nicht nur Spalten, sondern auch Primärschlüssel, eindeutige Constraints, Foreign Keys und sinnvolle Indexes.
Besonders wichtig sind klare referenceId-Werte. Sie sollten stabil, lesbar und eindeutig sein. Wenn du sie ständig änderst, kann Magento unnötige Drop-and-Create-Operationen erkennen. Bei Foreign Keys muss außerdem das Löschverhalten bewusst gewählt werden. CASCADE ist nicht automatisch richtig. Manchmal ist SET NULL oder ein bewusstes Verhindern der Löschung fachlich sinnvoller.
<?xml version="1.0"?>
<schema xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:framework:Setup/Declaration/Schema/etc/schema.xsd">
<table name="mironsoft_example_item" resource="default" engine="innodb" comment="Example Item">
<column xsi:type="int" name="item_id" unsigned="true" nullable="false" identity="true"
comment="Item ID"/>
<column xsi:type="int" name="example_id" unsigned="true" nullable="false" comment="Example ID"/>
<column xsi:type="varchar" name="sku" nullable="false" length="64" comment="SKU"/>
<constraint xsi:type="primary" referenceId="PRIMARY">
<column name="item_id"/>
</constraint>
<constraint xsi:type="foreign" referenceId="MIRONSOFT_EXAMPLE_ITEM_EXAMPLE_ID"
table="mironsoft_example_item" column="example_id"
referenceTable="mironsoft_example" referenceColumn="entity_id"
onDelete="CASCADE"/>
<constraint xsi:type="unique" referenceId="MIRONSOFT_EXAMPLE_ITEM_EXAMPLE_ID_SKU">
<column name="example_id"/>
<column name="sku"/>
</constraint>
<index referenceId="MIRONSOFT_EXAMPLE_ITEM_SKU" indexType="btree">
<column name="sku"/>
</index>
</table>
</schema>
5. Fehler 4: Whitelist ignorieren
Der vierte Fehler ist die ignorierte db_schema_whitelist.json. Bei deklarativem Schema muss Magento wissen, welche Tabellen, Spalten und Constraints vom Modul verwaltet werden dürfen. Die Whitelist schützt vor versehentlichem Löschen von Datenbankstrukturen. Wenn sie fehlt oder veraltet ist, können Schema-Änderungen in bestimmten Situationen nicht sauber ausgeführt werden.
Gerade bei entfernten Spalten oder Constraints ist die Whitelist relevant. Entwickler testen lokal oft nur das Hinzufügen neuer Spalten. Das Entfernen oder Umbenennen kommt später und fällt erst in Staging oder Produktion auf. Deshalb sollte die Whitelist im Team nicht als Nebenprodukt betrachtet werden, sondern als Teil der Schema-Änderung.
In Pull Requests sollte die Whitelist deshalb bewusst mitbetrachtet werden. Wenn db_schema.xml geändert wurde, aber die Whitelist unverändert bleibt, ist das nicht automatisch falsch, aber es ist ein Prüfpunkt. Besonders bei Modulen, die in mehreren Shops installiert sind, kann eine veraltete Whitelist später zu schwer erklärbaren Upgrade-Unterschieden führen.
# Mark-Shust wrapper from the project root:
bin/magento setup:db-declaration:generate-whitelist --module-name=Mironsoft_Example
Die generierte Datei liegt im Modul unter etc/db_schema_whitelist.json. Sie sollte versioniert werden, wenn das Modul deklaratives Schema verwaltet. Bei jeder relevanten Schema-Änderung prüfst du, ob die Whitelist aktualisiert werden muss.
6. Fehler 5: Änderungen ohne Upgrade-Strategie
Der fünfte Fehler ist fehlende Planung. Eine Tabelle neu anzulegen ist einfach. Schwieriger wird es, wenn Spalten umbenannt, Typen geändert, Daten migriert oder Constraints verschärft werden. Eine Änderung in db_schema.xml Magento 2 kann auf einer leeren Entwicklungsdatenbank problemlos wirken und trotzdem in Produktion riskant sein.
Beispiel: Eine nullable Spalte wird plötzlich nullable="false". Lokal klappt das, weil kaum Daten existieren. In Produktion enthält die Spalte aber Null-Werte. Das Upgrade kann scheitern. Deshalb braucht jede relevante Schema-Änderung eine kleine Upgrade-Strategie: Welche Daten existieren? Muss ein Data Patch vorher Werte füllen? Ist die Änderung rückwärtskompatibel? Wie groß ist die Tabelle?
<?php
declare(strict_types=1);
namespace Mironsoft\Example\Setup\Patch\Data;
use Magento\Framework\Setup\ModuleDataSetupInterface;
use Magento\Framework\Setup\Patch\DataPatchInterface;
/**
* Backfills missing titles before the column becomes required.
*/
final class BackfillMissingTitles implements DataPatchInterface
{
public function __construct(
private readonly ModuleDataSetupInterface $moduleDataSetup
) {}
public function apply(): self
{
$connection = $this->moduleDataSetup->getConnection();
$table = $this->moduleDataSetup->getTable('mironsoft_example');
$connection->update(
$table,
['title' => 'Untitled'],
'title IS NULL OR title = ""'
);
return $this;
}
public static function getDependencies(): array
{
return [];
}
public function getAliases(): array
{
return [];
}
}
7. Vergleich: db_schema.xml vs. Patch
Der saubere Umgang mit db_schema.xml Magento 2 beginnt mit der richtigen Zuständigkeit. Nicht jede Datenbankänderung gehört in dieselbe Datei. Struktur gehört in deklaratives Schema. Daten gehören in Data Patches. Einmalige, komplexe Strukturabläufe können Schema Patches benötigen. Wer diese Grenze einhält, vermeidet viele Upgrade-Probleme.
| Aufgabe | Richtiger Ort | Kommentar |
|---|---|---|
| Neue Tabelle | db_schema.xml | Deklarativer Zielzustand der Datenbank |
| Neue Spalte | db_schema.xml | Bei Pflichtspalten Datenbestand vorher prüfen |
| Initiale Datensätze | Data Patch | Nicht in Schema-Dateien verstecken |
| Datenmigration | Data Patch | Idempotent und bewusst planen |
| Komplexe Strukturmigration | Schema Patch | Nur wenn deklaratives Schema allein nicht reicht |
Ein guter Prüfpunkt vor jedem Merge ist die Frage: „Beschreibt diese Änderung Struktur oder Daten?“ Wenn es Struktur ist, gehört sie meist in db_schema.xml. Wenn es Daten sind, gehört sie in einen Patch. Wenn es beides ist, müssen Reihenfolge und Abhängigkeit bewusst definiert werden.
Mironsoft
Magento 2 Datenbank, Module und Upgrade-Strategien
Schema-Änderungen ohne Upgrade-Risiko planen?
Wir entwickeln Magento 2 Module mit sauberem deklarativem Schema, Data Patches, klarer Upgrade-Reihenfolge und prüfbaren Datenbankänderungen für Staging und Produktion.
Schema Review
db_schema.xml, Constraints, Indexes und Whitelist prüfen
Patches
Data Patches und Schema Patches sauber abgrenzen
Deployment
Upgrade-Reihenfolge und Datenbestand vorab bewerten
9. Zusammenfassung
db_schema.xml Magento 2 ist der richtige Ort für deklarative Tabellenstruktur. Die häufigsten Fehler entstehen, wenn Entwickler alte InstallScripts weiterverwenden, Datenänderungen im Schema verstecken, Constraints vernachlässigen, die Whitelist ignorieren oder Änderungen ohne Upgrade-Strategie deployen.
Die robuste Regel ist einfach: Struktur in db_schema.xml, Daten in Data Patches, komplexe Sonderfälle bewusst planen. Jede Schema-Änderung sollte lokal, auf Staging und mit realistischem Datenbestand geprüft werden. So bleiben Magento-Upgrades berechenbar.
Für professionelle Magento-Module ist das kein Zusatzaufwand, sondern Risikoreduktion. Saubere Datenbankänderungen verhindern Deployment-Abbrüche, Inkonsistenzen und teure Nacharbeiten. Je größer der Shop und je mehr Integrationen auf dieselben Tabellen zugreifen, desto wichtiger wird diese Disziplin.
db_schema.xml Magento 2 — Das Wichtigste auf einen Blick
Struktur
Tabellen, Spalten, Constraints und Indexes gehören in db_schema.xml.
Daten
Initiale Datensätze und Migrationen gehören in Data Patches, nicht in Schema-Dateien.
Whitelist
db_schema_whitelist.json bei relevanten Schema-Änderungen prüfen und versionieren.
Upgrade
Pflichtspalten, Typänderungen und Drops immer mit realem Datenbestand bewerten.
10. FAQ: db_schema.xml in Magento 2
1 Was ist db_schema.xml in Magento 2?
2 Soll man noch InstallSchema verwenden?
db_schema.xml, nicht in alte InstallScripts.3 Gehören Datenänderungen in db_schema.xml?
db_schema.xml beschreibt Struktur.4 Wofür ist db_schema_whitelist.json?
5 Wie generiert man die Whitelist?
bin/magento setup:db-declaration:generate-whitelist --module-name=Vendor_Module.