Η ανάπτυξη μιας εφαρμογής δεν σημαίνει μόνο την εφαρμογή νέων λειτουργιών ή την επιδιόρθωσή της. Μερικές φορές πρέπει να αντιστρέψετε τις αλλαγές και να επιστρέψετε στο προηγούμενο στάδιο ενός έργου. Ένα συχνό ζήτημα που μπορεί να προκύψει κατά την εργασία σε πολλαπλούς κλάδους συνδέεται με τη διατήρηση της κατάλληλης έκδοσης μιας δομής βάσης δεδομένων. Οι προγραμματιστές, οι οποίοι χρησιμοποιούν rails, έχουν έτοιμες λύσεις στη διάθεσή τους. Οι λύσεις αυτές υποστηρίζουν την υλοποίηση και τον έλεγχο των αλλαγών στη βάση δεδομένων - πρόκειται για μεταναστεύσεις. Δεν θα περιγράψω τον τρόπο λειτουργίας και τις δυνατότητες που προσφέρει - θα ήθελα να επικεντρωθώ στο πρόβλημα της διατήρησης της κατάλληλης έκδοσης μιας δομής βάσης δεδομένων κατά την εναλλαγή κλάδων.
Το επίπεδο βάσης δεδομένων μιας εφαρμογής είναι ένα ξεχωριστό ον και ελέγχεται μόνο από τις μεταναστεύσεις. Κατά τη δημιουργία νέων μεταναστεύσεων, θυμηθείτε να κάνετε τον προγραμματισμένο μετασχηματισμό μιας δομής βάσης δεδομένων αντιστρεπτό. Φυσικά, σε ακραίες περιπτώσεις, μπορούμε να αυξήσουμε IrreversibleMigration
στο κάτω μέθοδος. Αυτό θα μας ενημερώσει επίσης για το γεγονός ότι η μετανάστευση δεν μπορεί να αντιστραφεί. Υπάρχουν διάφοροι τύποι αλλαγών που κάνουμε στη μετάβαση - δημιουργία, τροποποίηση και αφαίρεση πινάκων, στηλών ή δεικτών. Οι λειτουργίες διαγραφής και τροποποίησης είναι οι πιο ευαίσθητες στις αλλαγές. Γιατί; Ας εξετάσουμε το ακόλουθο σενάριο: Εργαζόμαστε με τον κλάδο master, ο οποίος είναι το κύριο μονοπάτι εργασίας μας. Επί του παρόντος έχουμε έναν πίνακα:
class CreateArticles < ActiveRecord::Migration
def change
create_table :articles do |t|
t.string :name
t.text :description
t.string :status, null: false
t.timestamps null: false
end
end
end
Το μας Άρθρο
μοντέλο έχει τέτοιες επικυρώσεις που απαιτούν την παρουσία όνομα, περιγραφή και κατάσταση χαρακτηριστικά.
class Article < ActiveRecord::Base
validates :name, presence: true
validates :description, presence: true
validates :status, presence: true
end
Εφαρμόζουμε αλλαγές στο άρθρα τραπέζι στο χαρακτηριστικό υποκατάστημα ανάπτυξης και διαγράφουμε το κατάσταση στήλη.
class RemoveStatusColumnFromArticles < ActiveRecord::Migration
def change
remove_column :articles, :status, :string
end
end
Εκτελούμε τη μετάβαση:
$ [example/feature]: bundle exec rake db:migrate
== 20150605120955 RemoveStatusColumnFromArticles: migrating ===================
-- remove_column(:articles, :status, :string)
-> 0.0717s
== 20150605120955 RemoveStatusColumnFromArticles: migrated (0.0718s) ==========
Το σχήμα μιας βάσης δεδομένων αλλάζει:
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 @@ #
Συνιστάται έντονα να ελέγξετε αυτό το αρχείο στο σύστημα ελέγχου εκδόσεων που διαθέτετε.
-ActiveRecord::Schema.define(version: 20150605120350) do
+ActiveRecord::Schema.define(version: 20150605120955) do
createtable "articles", force: :cascade do |t|
t.string "όνομα"
t.text "description"
- t.string "status", null: false t.datetime "createdat", null: false
t.datetime "updated_at", null: false
end
end
Στη συνέχεια, δεσμεύουμε τις αλλαγές στο χαρακτηριστικό υποκατάστημα. Για να προσομοιώσουμε αυτό το πρόβλημα, αλλάζουμε τον τρέχοντα κλάδο σε master. Η δομή της βάσης άλλαξε από τη μετανάστευση, η οποία διαγράφει το κατάσταση στήλη στο χαρακτηριστικό υποκατάστημα. Ας προσπαθήσουμε να χρησιμοποιήσουμε την ακόλουθη εντολή:
Article.create!(name: "Kaboom", description: "Lorem ipsum...", status: "active")
Τι θα συμβεί μετά την εκτέλεση των προαναφερθέντων κωδικός? Το σφάλμα: ActiveRecord::UnknownAttributeError: άγνωστο χαρακτηριστικό 'status' για το άρθρο
και αυτό οφείλεται στην ασύμβατη έκδοση δομής μιας βάσης δεδομένων. Πριν από την αλλαγή του κλάδου σε master θα πρέπει να κάνουμε roll back τη μετανάστευση που διαγράφει την κατάσταση από τη στήλη Άρθρο τραπέζι.
Τι μπορούμε να κάνουμε για να ελέγξουμε αν πρέπει να ανατρέψουμε κάποιες μετακινήσεις πριν αλλάξουμε τους κλάδους; Με τη χρήση του συστήματος ελέγχου εκδόσεων (εδώ είναι git) μπορούμε να ελέγξουμε τη δουλειά μας δημιουργώντας ένα χρήσιμο ψευδώνυμο:
~/.gitconfig
[alias]
migrations = "!f() { git diff --name-only $1..$2 db/migrate | tr -d '[A-Za-z/_.]'; }; f"
Εκτελώντας το git μεταναστεύσεις κύριο χαρακτηριστικό
Η εντολή θα οδηγήσει στη λίστα των εκδόσεων μετάβασης, οι οποίες βρίσκονται στο χαρακτηριστικό κλάδους, και τα οποία δεν μπορούν να βρεθούν στο master.
$ [example/feature]: git migrations master feature
20150605120955
Χάρη σε αυτή την πληροφορία μπορούμε εύκολα να επαναφέρουμε τις αλλαγές που έγιναν στη δομή της βάσης δεδομένων πριν από τη μετάβαση στο master.
$ [example/feature]: bundle exec rake db:migrate:down VERSION=20150605120955
== 20150605120955 RemoveStatusColumnFromArticles: επαναφορά ===================
-- add_column(:articles, :status, :string)
-> 0.0009s
== 20150605120955 RemoveStatusColumnFromArticles: reverted (0.0045s) ==========
Ένα ακόμη πράγμα που πρέπει να κάνουμε μετά την επαναφορά της μετάβασης είναι να επαναφέρουμε την κατάσταση ενός σχήματος βάσης δεδομένων.
$ [example/feature]: κατάσταση git
Στο χαρακτηριστικό γνώρισμα του κλάδου
Αλλαγές που δεν έχουν δρομολογηθεί για δέσμευση:
(χρησιμοποιήστε το "git add ..." για να ενημερώσετε τι θα δεσμευτεί)
(χρησιμοποιήστε "git checkout -- ..." για να απορρίψετε τις αλλαγές στον κατάλογο εργασίας)
Τροποποιημένο: db/schema.rb
Δεν προστέθηκαν αλλαγές στη δέσμευση (χρησιμοποιήστε "git add" ή/και "git commit -a")
$ [example/feature]: git checkout db/schema.rb
$ [παράδειγμα/χαρακτηριστικό]: git status
Στο χαρακτηριστικό γνώρισμα branch
τίποτα προς δέσμευση, καθαρός κατάλογος εργασίας
Τώρα μπορούμε εύκολα να μεταβούμε στο master υποκατάστημα.
Το συγκεκριμένο παράδειγμα δεν είναι ένα πολύπλοκο πρόβλημα προς επίλυση, αλλά θα σας βοηθήσει να συνειδητοποιήσετε πόσο σημαντικό είναι να διατηρείται η δομή μιας βάσης δεδομένων κατά τη διάρκεια της αλλαγής στο πλαίσιο εργασίας.