Bedrijfslogica in de database met SchemaKeeper

Het doel van dit artikel is om aan de hand van de bibliotheek schema-keeper de tools te laten zien die het proces van databaseontwikkeling binnen PHP-projecten die PostgreSQL gebruiken, aanzienlijk vergemakkelijken.

Informatie uit dit artikel zal vooral nuttig zijn voor ontwikkelaars die de mogelijkheden van PostgreSQL maximaal willen benutten, maar problemen ondervinden bij het onderhouden van de bedrijfslogica die in de database is geplaatst.

Dit artikel zal de voordelen of nadelen van het opslaan van bedrijfslogica in de database niet beschrijven. Er wordt aangenomen dat de keuze al door de lezer is gemaakt.

De volgende vragen zullen worden behandeld:

  1. In welke vorm de dump van de database-structuur in het versiebeheersysteem (hierna VCS) moet worden opgeslagen
  2. Hoe wijzigingen in de database-structuur na het opslaan van de dump kunnen worden gevolgd
  3. Hoe wijzigingen in de database-structuur naar andere omgevingen te verplaatsen zonder conflicten en gigantische migratiebestanden
  4. Hoe het proces van parallel werken aan het project door meerdere ontwikkelaars kan worden georganiseerd
  5. Hoe veilig een groter aantal wijzigingen in de database-structuur naar de productieomgeving kan worden gedeployed

    SchemaKeeper is ontworpen voor het werken met opgeslagen procedures, geschreven in de taal PL/pgSQL. Testen met andere talen zijn niet uitgevoerd, dus het gebruik kan minder effectief of zelfs onmogelijk zijn.

In welke vorm de dump van de database-structuur in VCS moet worden opgeslagen

Bibliotheek schema-keeper biedt de functie saveDump, die de structuur van alle objecten uit de database opslaat als afzonderlijke tekstbestanden. Het resultaat is een map die de database-structuur bevat, verdeeld in gegroepeerde bestanden die gemakkelijk aan VCS kunnen worden toegevoegd.

Laten we de conversie van objecten uit de database naar bestanden aan de hand van enkele voorbeelden bekijken:

Type object
Schema
Naam
Relatief pad naar bestand

Tabel
public
accounts
.\/public\/tables\/accounts.txt

Opgeslagen procedure
public
auth(hash bigint)
.\/public\/functions\/auth(int8).sql

Representatie
booking
tariffs
.\/booking\/views\/tariffs.txt

De inhoud van de bestanden is een tekstuele weergave van de structuur van het specifieke databaseobject. Voor opgeslagen procedures is de inhoud van het bestand de volledige definitie van de opgeslagen procedure, die begint met het blok CREATE OR REPLACE FUNCTION.

Zoals te zien is in de bovenstaande tabel, bevat het pad naar het bestand informatie over het type, de schema en de naam van het object. Deze aanpak vergemakkelijkt de navigatie door de dump en de codebeoordeling van wijzigingen in de database.

Uitbreiding .sql Voor bestanden met de broncode van opgeslagen procedures is gekozen, zodat de IDE automatisch hulpmiddelen voor interactie met de database biedt bij het openen van het bestand.

Hoe wijzigingen in de database-structuur na het opslaan van de dump kunnen worden gevolgd

Door een dump van de huidige database-structuur in VCS op te slaan, kunnen we controleren of er wijzigingen in de database-structuur zijn aangebracht na het maken van de dump. In de bibliotheek schema-keeper is een functie voorzien voor het identificeren van wijzigingen in de database-structuur, verifyDump, die zonder bijwerkingen informatie over de verschillen retourneert.

Een alternatieve manier van controle is om de functie opnieuw aan te roepen, saveDump, met dezelfde directory op te geven en in VCS te controleren op wijzigingen. Aangezien alle objecten uit de database zijn opgeslagen in aparte bestanden, toont VCS alleen de gewijzigde objecten.
Het belangrijkste nadeel van deze methode is de noodzaak om bestanden opnieuw te schrijven om wijzigingen te zien.

Hoe wijzigingen in de database-structuur naar andere omgevingen te verplaatsen zonder conflicten en gigantische migratiebestanden

Dankzij de functie deployDump de broncode van opgeslagen procedures kan net zo worden aangepast als de gewone broncode van de applicatie. Nieuwe regels kunnen aan de code van opgeslagen procedures worden toegevoegd/verwijderd en wijzigingen kunnen onmiddellijk naar het versiebeheersysteem worden gestuurd, of opgeslagen procedures kunnen worden aangemaakt/verwijderd door de bijbehorende bestanden in de dumpdirectory aan te maken/verwijderen.

Bijvoorbeeld, om een nieuwe opgeslagen procedure in het schema public te creƫren, is het voldoende om een nieuw bestand met de extensie .sql in de directory public/functionsaan te maken, de broncode van de opgeslagen procedure erin te plaatsen, inclusief het blok CREATE OR REPLACE FUNCTION, en vervolgens de functie aan te roepen. deployDumpOp dezelfde manier worden opgeslagen procedures gewijzigd en verwijderd. Zo komt de code tegelijkertijd in VCS en in de database.

Als er een fout optreedt in de broncode van een opgeslagen procedure, of als er een discrepantie is tussen de bestandsnaam en de opgeslagen procedure, dan zal deployDump niet worden uitgevoerd, en verschijnt de foutmelding. deployDump.

Een discrepantie tussen opgeslagen procedures in de dump en de huidige database is onmogelijk bij gebruik van .sqlBij het creƫren van een nieuwe opgeslagen procedure is het niet nodig om handmatig de juiste bestandsnaam in te voeren. Het is voldoende dat het bestand de extensie deployDump heeft. Na het aanroepen zal

deployDump de foutmelding de juiste naam bevatten die kan worden gebruikt voor het hernoemen van het bestand.
maakt het mogelijk om parameters van de functie of het geretourneerde type te wijzigen zonder extra stappen, terwijl bij de klassieke aanpak eerst DROP FUNCTIONmoet worden uitgevoerd, en pas daarna CREATE OR REPLACE FUNCTION.

Helaas zijn er situaties waarin deployDump het niet mogelijk is om wijzigingen automatisch toe te passen. Bijvoorbeeld, als een triggerfunctie wordt verwijderd die door ten minste ƩƩn trigger wordt gebruikt. Dergelijke situaties worden handmatig opgelost met behulp van migratiebestanden.

Als de verantwoordelijk voor het overbrengen van wijzigingen in opgeslagen procedures ligt bij schema-keeper, dan moeten migratiebestanden worden gebruikt om de overige wijzigingen in de structuur over te brengen. Een goede bibliotheek voor het werken met migraties is doctrine/migrations.

Migraties moeten worden toegepast vóór de lancering deployDump. Dit maakt het mogelijk om alle wijzigingen in de structuur aan te brengen en problematische situaties op te lossen, zodat wijzigingen in opgeslagen procedures later probleemloos kunnen worden overgebracht.

Een uitvoerige beschrijving van het werken met migraties zal in de volgende secties worden gegeven.

Hoe het proces van parallel werken aan het project door meerdere ontwikkelaars kan worden georganiseerd

Het is noodzakelijk om een volledig initialisatiescript voor de database te maken, dat door de ontwikkelaar op zijn werkplek wordt uitgevoerd, zodat de structuur van de lokale database in overeenstemming is met de dump die in VCS is opgeslagen. Het is het gemakkelijkst om de initialisatie van de lokale database in drie stappen te verdelen:

  1. Importeren van een bestand met de basisstructuur, dat bijvoorbeeld base.sql
  2. zal worden genoemd.
  3. Aanroep deployDump

base.sql Toepassing van migraties deployDump, namelijk de — dit is het uitgangspunt waarboven migraties worden toegepast enbase.sql + migraties + deployDump = actuele structuur van de database pg_dump. Dit bestand kan worden gevormd met behulp van de utility base.sql . Het wordt

uitsluitend gebruikt bij de initialisatie van de database vanaf nul. Laten we het volledige initialisatiescript voor de database noemenrefresh.sh

  1. . Het werkproces kan er als volgt uitzien: Laten we het volledige initialisatiescript voor de database noemen De ontwikkelaar voert in zijn omgeving uit
  2. en ontvangt de actuele structuur van de database.De ontwikkelaar begint te werken aan de toegewezen taak, waarbij hij de lokale database aanpast aan de vereisten van de nieuwe functionaliteit ( ALTER TABLE ... ADD COLUMN
  3. enzovoort) saveDumpNa voltooiing van de taak roept de ontwikkelaar de functie aan
  4. , om de wijzigingen die in de database zijn aangebracht, in VCS vast te leggen. Laten we het volledige initialisatiescript voor de database noemen, dan verifyDumpDe ontwikkelaar voert opnieuw uit
  5. , wat nu een lijst van wijzigingen toont om op te nemen in de migratie. Laten we het volledige initialisatiescript voor de database noemen en verifyDumpDe ontwikkelaar draagt alle wijzigingen in de structuur over naar het migratiebestand, voert opnieuw uit verifyDump , en als de migratie correct is samengesteld, zal deze geen verschillen tonen tussen de lokale database en de opgeslagen dump.

Het hierboven beschreven proces is compatibel met de principes van gitflow. Elke branch in de VCS bevat zijn eigen versie van de dump, en bij het samenvoegen van branches vindt er een samenvoegen van dumps plaats. In de meeste gevallen zijn er na het samenvoegen geen extra stappen nodig, maar als in verschillende branches wijzigingen zijn aangebracht, bijvoorbeeld in dezelfde tabel, kan er een conflict ontstaan.

Laten we een conflictsituatie bekijken aan de hand van het voorbeeld: er is een branch develop, waaruit twee branches zijn afgeleid: feature1 en feature2, die geen conflicten hebben met develop, maar wel conflicten tussen elkaar. De taak is om beide branches samen te voegen in develop. Voor dit geval is het aanbevolen om eerst een van de branches samen te voegen in develop, en daarna develop in de resterende branch, terwijl de conflicten in de resterende branch worden opgelost, waarna de laatste branch in developwordt samengevoegd. Tijdens het oplossen van conflicten kan het nodig zijn om het migratiebestand in de laatste branch aan te passen, zodat het overeenkomt met de uiteindelijke dump, die de resultaten van de samenvoegingen omvat.

Hoe veilig een groter aantal wijzigingen in de database-structuur naar de productieomgeving kan worden gedeployed

Dankzij de dump van de actuele database-structuur in de VCS is het mogelijk om de productie-database te controleren op nauwkeurige overeenstemming met de vereiste structuur. Dit garandeert dat alle wijzigingen die de ontwikkelaars in gedachten hadden succesvol naar de productie-database zijn overgebracht.

Aangezien DDL in PostgreSQL is transacties, het wordt aangeraden om de volgende volgorde van deployment aan te houden, zodat, in geval van een onverwachte fout, het "pijnlijk" kan worden uitgevoerd. ROLLBACK:

  1. Start de transactie
  2. Voer binnen de transactie alle migraties uit
  3. Voer binnen dezelfde transactie deployDump
  4. Zonder de transactie af te sluiten, voer verifyDumpuit. Als er geen fouten zijn, voer COMMITuit. Als er fouten zijn, voer ROLLBACK

Deze stappen zijn vrij gemakkelijk in te passen in bestaande benaderingen voor het deployen van applicaties, inclusief zero-downtime.

Conclusie

Dankzij de hierboven beschreven methoden kan er het meeste uit "PHP + PostgreSQL" projecten worden gehaald, met een relatief kleine opoffering van gebruiksgemak in vergelijking met de implementatie van de gehele bedrijfslogica in de hoofdcode van de applicatie. Bovendien ziet het verwerken van gegevens in PL/pgSQL er vaak transparanter uit en vereist het minder code dan dezelfde functionaliteit geschreven in PHP.

Bron: habr.com

Koop betrouwbare webhosting met bescherming tegen DDoS, VPS VDS servers šŸ”„ Koop betrouwbare webhosting met bescherming tegen DDoS, VPS VDS servers | ProHoster