Logo der ic engineering & research GmbH
Rails und DB-Migration

Rails und DB-Migration

SQL92 != SQL92

Für ein Projekt sollten wir die Daten von einer MySQL-DB zu einer anderen DB migrieren. Unser erster Ansatz fusste auf der Tatsache, dass beide DBs SQL92 als gemeinsame Sprache verstehen. Also kurzerhand einen SQL-Dump erzeugt und diesen bei der anderen DB importiert. Leider schlug dieser Versuch fehl, da beide wohl SQL92 verstehen, aber im Detail doch etwas differenzierter interpretieren.

Zum Glück gibt es das Rails-Framework, das eine DB-Abstraktion bereit stellt. Offenbar hatte bereits vor uns dasselbe Problem und hat einen Rake-Task geschrieben, der den Inhalt der DB als YAML-Datei sichert. Mit diesem Backup kann anschliessend die neue DB befruchtet werden. Etwaige Unterschiede der verwendeten Datenbanken gleicht Rails bzw. Ruby für den Benutzer aus.

Dazu muss der Rake-Task backup.rake(external link) heruntergeladen werden und im Verzeichnis lib/tasks/ des Projektes gespeichert werden. Ist dies erledigt, kann die DB wie folgt gesichert werden:

rake db:backup:write
(in /Users/rOger/Documents/rails/icERtime/trunk)
Writing invoices...
Writing timerecords...
Writing users...

Auf dem Zielsystem oder aber in einem anderen Environment (RAILS_ENV=production dem Befehl voranstellen) kann dann der DB-Dump wie folgt wieder eingelesen werden:

rake db:backup:read

Achtung: Damit werden allenfalls vorhandene Daten gelöscht!

Quelle: http://blog.leetsoft.com/2006/5/29/easy-migration-between-databases(external link)

 

Problem: BigDecimal can't be coerced into BigDecimal

Da seit Rails 1.2 BigDecimal unterstützt wird, dies in ActiveRecord aber noch nicht richtig bzw. komplett in einem YAML-Format unterstützt wird, muss man an das Backup-Skript etwas Hand anlegen. Es muss nach der Namespace-Definition folgende Zeilen eingefügt werden:

require 'yaml'
require 'bigdecimal'
class BigDecimal
   def to_yaml(opts={})
     YAML::quick_emit(object_id, opts) do |out|
       out.scalar("tag:induktiv.at,2007:BigDecimal", self.to_s)
     end
   end
 end
 YAML.add_domain_type("induktiv.at,2007", "BigDecimal") { |type, val|   BigDecimal.new(val) }

Danach müssen die Daten erneut exportiert werden, damit die Daten korrekt ins YAML-File wandern. Anschliessend können die Daten auch ohne Probleme wieder eingelesen werden.

Quelle: http://blog.induktiv.at/archives/6-YAML-and-BigDecimal-a-temporary-solution.html(external link)

 

ic engineering & research GmbH
Oberfeldstrasse 120d
CH-8408 Winterthur
Telefon 052 223 13 70