Een app ontwikkelen betekent niet alleen nieuwe functies implementeren of patchen. Soms moet je de wijzigingen terugdraaien en teruggaan naar de vorige fase van een project. Een vaak voorkomend probleem bij het werken aan meerdere takken heeft te maken met het onderhouden van de juiste versie van een databasestructuur. Programmeurs die rails gebruiken, hebben kant-en-klare oplossingen tot hun beschikking. Deze oplossingen ondersteunen de implementatie en controle van databaseveranderingen - dit zijn migraties. Ik zal niet beschrijven hoe het werkt en welke mogelijkheden het biedt - ik wil me richten op het probleem van het behouden van de juiste versie van een databasestructuur tijdens het wisselen van filiaal.
De databaselaag van een app is een apart wezen en wordt alleen bestuurd door migraties. Denk er bij het maken van nieuwe migraties aan om de geplande transformatie van een databasestructuur omkeerbaar te maken. Natuurlijk kunnen we in extreme gevallen Onomkeerbare migratie
in de naar beneden methode. Dit zal ons ook informeren over het feit dat de migratie niet kan worden teruggedraaid. Er zijn verschillende soorten wijzigingen die we in de migratie aanbrengen - tabellen, kolommen of indexen aanmaken, wijzigen en verwijderen. Verwijder- en wijzigingsbewerkingen zijn het meest gevoelig voor wijzigingen. Waarom? Laten we het volgende scenario bekijken: We werken met de master branch, wat ons belangrijkste werkpad is. Op dit moment hebben we één tabel:
klasse Artikelen aanmaken < ActiveRecord::Migratie
def verandering
create_table :articles do |t|
t.string :naam
t.tekst :beschrijving
t.string :status, null: false
t.timestamps nul: vals
einde
einde
einde
Onze Artikel
model heeft dergelijke validaties die de aanwezigheid van naam, beschrijving en status attributen.
Klasse Artikel < ActiveRecord::Base
valideert :naam, aanwezigheid: waar
valideert :description, aanwezigheid: waar
valideert :status, aanwezigheid: waar
einde
We voeren veranderingen door in onze artikelen tafel op functie ontwikkelingstak en verwijderen we de status kolom.
class RemoveStatusColumnFromArticles < ActiveRecord::Migration
afbreken
verwijder_kolom :artikelen, :status, :string
einde
einde
We voeren de migratie uit:
$ [voorbeeld/feature]: bundle exec rake db:migrate
== 20150605120955 RemoveStatusColumnFromArticles: migreren ===================
-- remove_column(:articles, :status, :string)
-> 0.0717s
== 20150605120955 RemoveStatusColumnFromArticles: gemigreerd (0.0718s) ==========
Het schema van een database verandert:
diff --git a/db/schema.rb b/db/schema.rb
index 2a100a9..76438c1 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,14 +11,13 @@ #
Het wordt sterk aangeraden om dit bestand in te lezen in je versiebeheersysteem.
-ActiveRecord::Schema.define(version: 20150605120350) do
+ActiveRecord::Schema.define(versie: 20150605120955) do
createtable "articles", force: :cascade do |t|
t.string "naam
t.tekst "beschrijving
- t.string "status", null: false t.datetime "createdat", null: false
t.datetime "updated_at", null: false
einde
einde
Vervolgens leggen we de wijzigingen vast in de functie branch. Om dit probleem te simuleren, schakelen we de huidige branch naar master. De basisstructuur is veranderd door migratie, die de status kolom op de functie vertakking. Laten we proberen het volgende commando te gebruiken:
Artikel.create!(naam: "Kaboom", beschrijving: "Lorem ipsum...", status: "actief")
Wat gebeurt er na het uitvoeren van de bovenstaande code? De fout: ActiveRecord::UnknownAttributeError: onbekend attribuut 'status' voor artikel
zal worden verhoogd en dat komt door de incompatibele structuurversie van een database. Voordat we de branch naar master veranderen, moeten we de migratie terugdraaien die de status kolom van de Artikel tafel.
Wat kunnen we doen om te controleren of we sommige migraties moeten terugdraaien voordat we de branches wisselen? Met behulp van het versiebeheersysteem (hier is het git) kunnen we ons werk controleren door een handige alias aan te maken:
~/.gitconfig
[alias]
migrations = "!f() { git diff --name-only $1..$2 db/migrate | tr -d '[A-Za-z/_.]'; }; f"
De Git migraties masterfunctie
commando resulteert in de lijst met migratieversies, die te vinden zijn op functie takken, en die niet te vinden zijn op master.
$ [voorbeeld/feature]: git migraties master functie
20150605120955
Dankzij deze informatie kunnen we de wijzigingen in de databasestructuur gemakkelijk terugdraaien voordat we overschakelden naar master.
$ [voorbeeld/feature]: bundle exec rake db:migrate:down VERSION=20150605120955
== 20150605120955 RemoveStatusColumnFromArticles: terugdraaien ===================
-- add_column(:articles, :status, :string)
-> 0.0009s
== 20150605120955 RemoveStatusColumnFromArticles: terugdraaien (0.0045s) ==========
Nog iets dat we moeten doen na het terugdraaien van de migratie is het herstellen van de status van een databaseschema.
$ [voorbeeld/feature]: git status
Op branch functie
Wijzigingen niet ge-staged voor commit:
(gebruik "git add ..." om bij te werken wat gecommit zal worden)
(gebruik "git checkout -- ..." om veranderingen in de werkmap te verwijderen)
gewijzigd: db/schema.rb
geen veranderingen toegevoegd aan commit (gebruik "git add" en/of "git commit -a")
$ [voorbeeld/feature]: git checkout db/schema.rb
$ [voorbeeld/feature]: git status
Op branch functie
niets om vast te leggen, werkmap schoon
Nu kunnen we gemakkelijk overschakelen naar de master vestiging.
Het gegeven voorbeeld is geen ingewikkeld probleem om op te lossen, maar het zou je moeten helpen beseffen hoe belangrijk het is om de structuur van een database te behouden tijdens de verandering in de werkcontext.