Declaratief Schema-functie in Magento 2 • Proudnerds
Allereerst, wat is declaratief schema in Magento 2? Het is een nieuwe manier van werken met databases zonder dat ontwikkelaars voor elke nieuwe moduleversie verschillende scripts hoeven te schrijven. Het werd in 2018 geïntroduceerd met Magento 2.3 en het is een van de grote veranderingen. In dit artikel leert u hoe u een declaratief schema kunt gebruiken en gegevenspatches kunt toepassen.
Waarom declaratief schema?
Wat zijn de voordelen van het gebruik van declaratief schema? Kortom, daarvoor moesten we databasescripts schrijven in PHP, wat geen perfecte oplossing is. Dat komt omdat wanneer u Magento upgradet naar een versie die meerdere releases vóór de geïnstalleerde versie ligt, alle upgradescripts tussen die twee versies nog steeds worden uitgevoerd. Dit zorgt met andere woorden voor onnodig complexe situaties. De nieuwe aanpak stelt ons in staat om de uiteindelijke staat van de database aan te geven en het systeem past zich daar automatisch aan aan. Bovendien worden gegevens verwijderd wanneer u de module verwijdert.
Declaratieve schemaconfiguratie
Laten we zeggen dat je een module hebt met versie 1.0.0 en de laatste versie is 1.0.3. Wanneer u een upgrade uitvoert, worden ook scriptwijzigingen voor 1.0.1 en 1.0.2 toegepast. Dit is niet ideaal omdat Magento wijzigingen blindelings toepast. Dat betekent dat je in de ene versie een kolom kunt introduceren en deze in de volgende kunt verwijderen. Dat is een van de problemen die declaratief schema elimineert. Hiermee bepaalt Magento de verschillen tussen de huidige tabelstructuur en hoe deze eruit zou moeten zien.
U moet een nieuwe module maken voordat we ons gaan verdiepen in het werken met databases.
Maak in de map Module/etc/ db_schema.xml aan. Dit is het bestand waarin u uw tabellen, kolommen, vrijwel alles wat u nodig heeft, definieert. Ik heb een eenvoudig voorbeeld gemaakt met twee tabellen om je te laten zien hoe je het moet doen.
<?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="inchoo_declarative_schema1" resource="default" engine="innodb" comment="Proudnerds Table 1">
<column xsi:type="int" name="table_1_id" padding="10" unsigned="true" nullable="false" identity="true" comment="ID"/>
<column xsi:type="varchar" name="name" comment="Name"/>
<constraint xsi:type="primary" referenceId="PRIMARY">
<column name="table_1_id"/>
</constraint>
</table>
<table name="inchoo_declarative_schema2" resource="default" engine="innodb" comment="Proudnerds Table 2">
<column xsi:type="int" name="table_2_id" padding="10" unsigned="true" nullable="false" identity="true" comment="ID"/>
<column xsi:type="text" name="content" comment="Content"/>
<constraint xsi:type="primary" referenceId="PRIMARY">
<column name="table_2_id"/>
</constraint>
</table>
</schema>
Als u setup:upgrade uitvoert, worden er twee tabellen gemaakt, inchoo_declarative_schema1 en inchoo_declarative_schema2 met ID’s en een extra kolom. Zoals u kunt zien, zijn de ID-kolommen ingesteld als primaire sleutel.
Tafels
Het tabelknooppunt kan drie verschillende typen subknooppunten bevatten:
Kolom
Kolom wordt gebruikt om een kolom in de tabel te definiëren. Zijn “xsi:type” definieert zijn type (boolean, date, int…). Er zijn meer attributen behalve degene die je in onze afbeelding kunt zien (zoals standaard, precisie, schaal), maar in dit artikel zal ik niet in detail treden over wat elk van hen doet.
Dwang
Constraint bevat altijd de kenmerken “type” en “referenceId”. Type kan primair, uniek of buitenlands zijn. ReferenceId is een aangepaste id die we gebruiken voor relatietoewijzing in het kader van db_schema.xml-bestanden. De aanbevolen manier om de waarde van het kenmerk referenceId in te stellen, is door de waarde uit db_schema_whitelist.json te gebruiken. Lees verder voor een uitleg over het genereren van een witte lijst.
Inhoudsopgave
We gebruiken de index-subnode voor het versnellen van DQL-bewerkingen en het bevat twee attributen, “referenceId” en “indexType”. We hebben al uitgelegd wat referenceId is en hoe je de waarde ervan kunt krijgen. De waarde van indexType moet btree, fulltext of hash zijn.
Als je de setup-upgrade hebt uitgevoerd en je herinnert je dat je een kolom of iets anders bent vergeten, maak je dan geen zorgen, je hebt geen extra bestanden nodig! Je kunt gewoon alles toevoegen wat je hebt gemist in dezelfde db_schema.xml en bij de volgende setup-upgrade wordt je database bijgewerkt.
Hetzelfde geldt voor het verwijderen van tabellen of kolommen. Verwijder eenvoudig de tabel of kolom uit db_schema.xml en voer de setup-upgrade uit. Als u echter een kolom wilt verwijderen die in een andere module is gedeclareerd, moet u deze opnieuw declareren met het kenmerk “disabled=true”. Het is ook belangrijk om te weten dat u een kolom alleen kunt neerzetten als deze in het bestand db_schema_whitelist.json bestaat.
Het hernoemen van tabellen en kolommen wordt ondersteund en hier leest u hoe u dit doet. Het enige wat u hoeft te doen is het kenmerk “name” in de tabeldeclaratie te wijzigen en het kenmerk “onCreate” toe te voegen. In ons geval zou de tabeldeclaratie er als volgt uitzien als we inchoo_declarative_schema1 willen hernoemen:
<table name="inchoo_declarative_schema1_renamed" onCreate="migrateDataFromAnotherTable(inchoo_declarative_schema1)">
<column xsi:type="int" name="table_1_id" padding="10" unsigned="true" nullable="false" identity="true"
comment="ID"/>
<column xsi:type="varchar" name="name" comment="Name"/>
<constraint xsi:type="primary" referenceId="PRIMARY">
<column name="table_1_id"/>
</constraint>
</table>
Hernoemen doe je door de tabel met de oude naam daadwerkelijk te verwijderen en de tabel met de nieuwe naam aan te maken met behoud van al je gegevens.
Oefening
Een van de beste nieuwigheden met deze aanpak is de droogloopmodus. Hiermee kunt u alle DDL SQL-instructies bekijken die tijdens de installatie zijn gegenereerd. Uw gegevens en schema’s blijven hetzelfde, dus dit is in wezen een testtool.
U kunt de droogloopmodus inschakelen met de volgende opdrachten:
bin/magento setup:install --dry-run=1
of
bin/magento setup:upgrade --dry-run=1
Nadat het is uitgevoerd, maakt Magento een log aan op var/log/dry-run-installation.log. Daar kunt u de gegenereerde DDL SQL-statements zien en deze gebruiken voor debuggen of optimaliseren.
Ik heb nog een kolom toegevoegd aan de tabel inchoo_declarative_schema2 en de setup-upgrade uitgevoerd met de droge run-modus ingeschakeld:
In het logboek kun je zien dat ik heb geprobeerd kolom ‘log_test’ toe te voegen, maar het zal niet echt gebeuren voordat ik de setup-upgrade heb uitgevoerd zonder de droge run-modus. Uiterst handig, niet?
Witte lijst
Aangezien achterwaartse compatibiliteit moet worden gehandhaafd, verwijdert het declaratieve schema niet automatisch databasetabellen, kolommen of sleutels die niet zijn gedefinieerd in db_schema.xml.
Dit is een van de redenen waarom we db_schema_whitelist.json hebben. Het toont een geschiedenis van alle tabellen, kolommen en sleutels die zijn toegevoegd met een declaratief schema en het is vereist voor drop-bewerkingen. Nadat u de setup-upgrade of -installatie hebt uitgevoerd, kunt u deze genereren met de volgende opdracht:
bin/magento setup:db-declaration:generate-whitelist
Dit maakt een bestand aan in uw etc-map met de naam db_schema_whitelist.json. Onze db_schema_whitelist.json ziet er bijvoorbeeld als volgt uit:
Er zijn opties die u aan het einde van die opdracht kunt toevoegen. U kunt bijvoorbeeld “–module-name=YourModule” gebruiken om de module op te geven waarvoor u een witte lijst wilt genereren. Op dezelfde manier kunt u ook “–module-name=all” instellen, hoewel het standaard een witte lijst voor alle modules genereert.
Het wordt aanbevolen om een nieuwe witte lijst te genereren voor elke release die wijzigingen bevat in db_schema.xml.
Gegevenspatches
In dit artikel geef ik je alleen een overzicht van wat datapatches zijn en waarom we ze gebruiken. Kortom, datapatches zijn klassen met instructies voor het wijzigen van gegevens. Patches worden slechts één keer toegepast en een lijst van die aangebrachte patches is te vinden in de patch_list-tabel in de database. Alle patches die niet zijn toegepast, worden toegepast wanneer u de setup-upgrade uitvoert.
U moet uw gegevenspatch maken in de map Module/Setup/Patch/Data. Het moet MagentoFrameworkSetupPatchDataPatchInterface implementeren.
Zoals je kunt zien, hebben we 3 methoden, getDependencies(), getAliases() en apply(). Omdat patches afhankelijk kunnen zijn van andere patches, kunt u hun afhankelijkheden definiëren in de methode getDependencies() :
public static function getDependencies() {
return [ ModuleSetupPatchDataPatch::class ];
}
Met de methode getAliases() kunnen we patch-aliassen toevoegen als we de naam van de patch moeten wijzigen.
De methode die u het meest zult gebruiken, is Apply(). Dit is waar je code komt die je in de patch wilt toepassen. Dit is bijvoorbeeld de methode apply() in de klasse MagentoCatalogSetupPatchDataDisallowUsingHtmlForProductName:
Kortom, de declaratieve schemafunctie maakt het voor ontwikkelaars gemakkelijker om met de database te werken. Bovendien is het proces sneller en veel eenvoudiger dan voorheen, wat betekent dat de prestaties zullen verbeteren.
Hoewel het implementeren van declaratief schema momenteel niet vereist is voor Magento 2.3, wordt het ten zeerste aanbevolen om het te leren, aangezien het in de toekomst upgradescripts zal vervangen.
En als je wilt zien hoe we je kunnen helpen met je ontwikkelproces, neem dan contact op om het gesprek aan te gaan!