Migration nach PostgresSQL on Rails

Im Segment der relationalen Datenbanken ist PostgreSQL oft die erste Wahl. Dafür sprechen viele Gründe.
Einige wenige davon sind:

  • JSON Datentyp (und JSON Funktionen)
  • HSTORE datatype for storing non-relational data as key value pair (Dokumentenbasierte Datanbank Emulation möglich)
  • Unterstützung zusätzlicher Datentypen, wie Boolean und Range
  • Filter Based Indexes (Indizierung einer bestimmten Spalte anhand eines Filters)
  • LIMIT und OFFSET
  • Volltextsuche Features
  • Geodaten (durch Postgis Erweiterung)

Spätestens, wenn die Anwendung nicht länger Prototyp ist, sondern relevant und produktive Daten enthalten soll, macht es Sinn zu PostgreSQL zu migrieren.

PostgreSQL Vorbereitung

Zunächst einmal die Installation von PostgreSQL:

# Ubuntu oder DIstribution der Wahl
sudo apt-get update
sudo apt-get install postgresql postgresql-contrib

Oft ist der lokale User mit peer Anmeldung eingerichtet. Für alle anderen User (z.B. das Datenbankaccount der Anwendung) sollte allerdings md5 sein, um Passwortabfrage anzufordern:

# /etc/postgresql/9.5/main/pg_hba.conf
TYPE	DATABASE	USER		ADDRESS		METHOD
local	all		christian			peer            
local	all		all				md5

Die Konfigurationsänderungen werden allerdings erst nach Neustart des Postgres Servers wirksam:

sudo service postgresql restart

Um den Datenbankuser für die Applikation enlegen zu können, muss sich zunächst einmal mit dem Systemuser postgres an der Template Datenbank postgres angemeldet werden:

sudo -i -u postgres
psql postgres

Das Account kann angelegt werden (allerdings nur mit eingeschränkten Rechten):

create user alice with password 'AwEs0Me!' createdb;

PostgreSQL on Rails

Die Ruby on Rails Anwendung benötigt den PostgreSQL Adapter:

# Gemfile
gem 'pg'

Der alte Datenbankadapter (SQLite3, MySQL …) kann gelöscht werden.
Nach dem:

bundle install

kann nun in der Datenbankkonfiguration der Postgres Adapter mit dem zuvor angelegten Datenbankuser konfiguriert werden:

# config/database.yml
default: &default
  adapter: postgresql
  encoding: unicode
  pool: 5
  username: alice
  password: 'AwEs0Me!'

production:
  <<: *default
  database: awesome_app_production

Die Datenbank wird erstellt:

rake db:create

Datenbank Migration

Um die Daten und Struktur aus dem alten DBMS nach Postgres zu überführen sind allerdings ein paar Schritte notwendig. So zum Beispiel sind Datenbankspezifische Datentypen zu beachten.
Sicherlich könnte ein Dump aus der alten Datenbank generiert werden, das erstellte SQL script per Hand modifiziert werden und mit pg_restore in der Postgres Datenbank wiederhergestellt werden. Allerdings ist das etwas aufwendig.
Eine schnelle Migration kann auch mit einem ORM durchgeführt werden, der die Inkonsistenzen auflöst. Eine Migration von SQLite3 nach Postgres mit Sequel:

gem install sequel
sequel -C sqlite://db/production.sqlite3 postgres://alice:AwEs0Me!@localhost/awesome_app_production

Die Datenbank wurde migriert und kann nun verwendet werden.
In der Postgres console:

psql -U alice -d awesome_app_production

mit der Auflistung der Tabellen:

# awesome_app_production
\d+

 Schema	| Name			| Typ		| Eigentümer	| Größe		| Beschreibung
--------+-----------------------+---------------+---------------+---------------+--------------
 public | users			| Tabelle	| alice		| 8192 bytes	| 
 public	| schema_migrations	| Tabelle	| alice		| 16 kB		|