FastJacks Paralleluniversum

Die Welt, in der ich lebe

PostgreSQL und Mac OS X 10.5

Stichwörter: leopard, macosx, postgresql

Wer in der Hoffnung kommt, ich hätte nach meiner Anleitung für PostgreSQL auf Mac OS X Tiger eine Fortsetzung für Mac OS X Leopard geschrieben, der kann nun aufatmen. Die neue Anleitung gibt es hier

Eingetragen von FastJack am 4. November 2007 um 04:05

Neue Array-Operatoren in PostgreSQL 8.2

Stichwörter: array, operator, postgresql

Seit Version 8.2 verfügt PostgreSQL über einige neue Operatoren, die Arrays in SQL erst richtig nützlich machen. Konnte man bislang (bis Version 8.1) nur möglich die Arrays zu verketten, Elementweise zu vergleichen oder einzelne Elemente aus dem Array wieder herauszufischen, so kann man nun auch Testen, ob zwei Arrays über gemeinsame Elemente verfügen oder gar ein Array vollständig im anderen enthalten ist. Diese neuen Operatoren sind @>, <@ und &&.

Mit @> kann man prüfen, ob das Array links des Operators eine Obermenge des Arrays rechts des Operators ist. Das Gegenstück dazu ist <@. Es prüft, ob das Array links des Operators eine Untermenge des Arrays rechts des Operators ist. Zu guter Letzt kann man noch mit && überprüfen, ob die Arrays Elemente gemeinsam haben.

Hier ein paar Beispiele, wie sich die neuen Operatoren einsetzen lassen.

test=> SELECT ARRAY[1, 2, 3, 4, 5, 6, 7, 8, 9] @> ARRAY[2, 4, 6, 8];
 ?column? 
----------
 t
(1 row)

Hier muß ich wohl nichts weiter dazu sagen. Alle Elemente des zweiten Arrays sind auch im ersten enthalten, also ist das Ergebnis true.

test=> SELECT ARRAY[2, 4, 6, 8, 10] <@ ARRAY[1, 2, 3, 4, 5, 6, 7, 8, 9];
 ?column? 
----------
 f
(1 row)

Hier ist das Ergebnis false, da die 10 aus dem ersten Array nicht im zweiten enthalten ist. Somit ist das erste Array keine Untermenge des zweiten Arrays.

test=> SELECT ARRAY[2, 4, 6, 8, 10] && ARRAY[1, 2, 3, 4, 5, 6, 7, 8, 9];
 ?column? 
----------
 t
(1 row)

Hier dagegen ist das Ergebnis true. Die beiden Arrays haben Elemente gemeinsam (wenn auch nicht alle).

Wer noch mehr über Arrays und die dazugehörigen Operatoren in PostgreSQL lesen möchte, kann dies in der Doku tun.

Eingetragen von FastJack am 6. Juli 2007 um 23:04

SQL ohne Schleifen

Stichwörter: activerecord, extract, postgresql, rails, rubyonrails, schleifenlos, sql

Manche Aufgaben schreien geradezu danach, mit Schleifen gelöst zu werden. In SQL ist dies selten nötig. In meinem Beispiel wollten wir für jeden Monat des letzten Jahres die Häufigkeit eines bestimmten Ereignisses errechnen um es graphisch darzustellen. Mein Kollege, der an dieser Stelle besser anonym bleiben möchte, schlug schon vor, die Abfrage 12× mit unterschiedlichen Bedingungen abzuschießen.

Mir fiel ein, daß PostgreSQL über Funktionen verfügt, mit denen man aus einem Datum Jahr/Monat/Tag (und einiges Mehr) extrahieren kann. Die Funktion heißt sinnvollerweise extract. Damit kann man das Problem mit einer einzigen Abfrage erschlagen. Dies sieht dann so aus:

SELECT EXTRACT(month FROM created_on) AS month, COUNT(*) AS occurences
FROM my_event_log
WHERE EXTRACT(year FROM created_on)=2006
GROUP BY EXTRACT(month FROM created_on)
ORDER BY EXTRACT(month FROM created_on)

Dies läßt sich auch prima in Rails verwenden.

events = MyEventLog.count(:conditions => [ "EXTRACT(year FROM created_on)=?", 2006],
                          :group => "EXTRACT(month FROM created_on)",
                          :order => "EXTRACT(month FROM created_on)")

Es sollte an dieser Stelle jedoch nicht unerwähnt bleiben, daß durch die Verwendung von Funktionen wie extract in Verbindung mit ActiveRecord, der datenbankagnostische Aspekt von ActiveRecord verloren geht, da nicht alle Datenbanken die gleichen Funktionen unterstützen. Aber vermutlich ist datenbankagnostische Programmierung eh eine utopische Vision.

Eingetragen von FastJack am 23. April 2007 um 15:54

Es ist alles eine Ansichtssache

Stichwörter: postgresql, rails, ruby, ruby on rails, rule, schema, view

Wir stellen in der Firma derzeit Teile unserer alten Software auf eine hippe und coole Rails-Anwendung um. Solange unsere Anwendung nicht fertig ist, muß die alte und die neue Software parallel laufen und auf die gleichen Daten zugreifen können. Da wird die alte Software nicht ändern können und wollen, muß sich Rails entsprechend anpassen. Wir sind ja agil, oder? Ich hätte natürlich die Tabellen gerne möglichst Rails-konform, doch die alten Daten strotzen nur so vor Altlasten: unverständliche oder irreführende mixed-case Namen. Kombiniert man das mit PostgreSQL, hat man ein Problem, da der PostgreSQL-Adapter in Rails die Namen nicht quotet, was PostgreSQL dazu veranlaßt, alle Namen in Kleinbuchstaben zu verwandeln.

mehr…

Eingetragen von FastJack am 27. Februar 2007 um 20:23

PostgreSQL auf Mac OS X, diesmal mit Syslog-Logging

Stichwörter: datenbank, mac, macosx, osx, postgresql, server, syslog

Ich hatte vor einer Weile geschrieben, wie man PostgreSQL auf Mac OS X sauber installiert. Das klappt zwar prima, doch die Logfiles waren ein wenig chaotisch. Bei der Installation von PostgreSQL 8.2 habe ich also beschlossen, via Syslog zu loggen. Die eigentliche Installation läuft wie im letzten Artikel beschrieben ab. Erst bei Punkt 10 mußte ich von der alten Anleitung abweichen.

In der /Users/Shared/PostgreSQL/data/postgresql.conf habe ich folgende Änderungen durchgeführt:

--- postgresql.conf.orig  2006-12-08 13:29:39.000000000 +0100
+++ postgresql.conf 2006-12-08 13:31:28.000000000 +0100
@@ -221,6 +221,7 @@
 
 # - Where to Log -
 
+log_destination = "syslog"
 #log_destination = 'stderr'    # Valid values are combinations of 
          # stderr, syslog and eventlog, 
          # depending on platform.
@@ -252,6 +253,7 @@
 
 # These are relevant when logging to syslog:
 #syslog_facility = 'LOCAL0'
+syslog_facility = 'LOCAL1'
 #syslog_ident = 'postgres'
 
 
@@ -313,6 +315,7 @@
 #log_connections = off
 #log_disconnections = off
 #log_duration = off
+log_line_prefix = '%u@%h:/%d '
 #log_line_prefix = ''      # Special values:
          #   %u = user name
          #   %d = database name
@@ -331,6 +334,7 @@
          #   %% = '%'
          # e.g. '<%u%%%d> '
 #log_statement = 'none'      # none, ddl, mod, all
+log_statement = 'all'
 #log_hostname = off
 
 

Damit habe ich PostgreSQL gesagt, es möge seine Nachrichten an den Syslog senden. Nun muß der Syslog noch wissen, was er damit anstellen soll. Das steht in der /etc/syslog.conf.

--- syslog.conf.orig  2006-12-08 13:34:26.000000000 +0100
+++ syslog.conf 2006-12-08 13:34:11.000000000 +0100
@@ -17,5 +17,6 @@
 install.*            /var/log/install.log
 install.*            @127.0.0.1:32376
 local0.*           /var/log/ipfw.log
+local1.*           /var/log/pgsql/pgsql.log
 
 *.emerg              *

Fast geschafft. Jetzt mußte ich nur noch aus dem Launchd-Skript die Zeilen entfernen, die dem PostgreSQL-Server gesagt haben, daß er sich selbst um die Logfiles kümmern soll.

--- org.postgresql.postmaster.plist.orig  2006-12-08 13:37:13.000000000 +0100
+++ org.postgresql.postmaster.plist 2006-12-08 13:37:25.000000000 +0100
@@ -15,10 +15,6 @@
    <string>redirect_stderr=YES</string>
    <string>-c</string>
    <string>log_connections=YES</string>
-   <string>-c</string>
-   <string>log_directory=/var/log/pgsql</string>
-   <string>-c</string>
-   <string>log_filename=postgres_log</string>
  </array>
  <key>ServiceDescription</key>
  <string>PostgreSQL Server</string>

Dann habe ich nur noch ein leeres Logfile für den Syslog mit sudo touch /var/log/pgsql/pgsql.log angelegt. (Es könnte nötig sein, vorher das dazugehörige Verzeichnis mit sudo mkdir /var/log/pgsql anzulegen). Damit der Syslog nun seine Konfigurationsdatei neu einliest, habe ich ihn mit sudo killall -HUP syslogd angeregt, sich zu restarten.

Nun kann der PostgreSQL wie in der alten Anleitung gestartet werden.

Eingetragen von FastJack am 8. Dezember 2006 um 14:45

MS Access, pgsqlODBC und Booleans

Stichwörter: boolean, msaccess, odbc, pgsqlodbc, postgresql, sql, windows

pgsqlODBC macht in den Standardeinstellungen einige sehr sonderbare Sachen. Eine Spalte mit Booleans erscheint in MS Access als Textfeld. Das führt dann natürlich zu einigen Problemen mit Checkboxen. Access meint dann, das Feld wäre zu klein, um den Wert zu speichern. Dabei beherrscht MS Access Booleans. Man muß nur den pgsqlODBC-Treiber überzeugen, das ganze für MS Access verständlich zu präsentieren. Hierzu müssen nur 2 Optionen in der ODBC-Verbindung geändert werden. Die Optionen finden sich unter Datasource

  1. Bools as Char muß ausgeschaltet werden
  2. True is -1muß eingeschaltet werden

Verknüpft man die Tabellen nun (erneut), werden sie in MS Access auch korrekt als Ja/Nein angezeigt und können auch von Checkboxen verwendet werden.

Eingetragen von FastJack am 12. Juni 2006 um 18:03

Spielereien mit Rules und Check Constraints in PostgreSQL

Stichwörter: constraint, postgresql, rule, sql

Ich hatte heute das Problem, daß ich in der Datenbank Zeiträume (Start- und Enddatum) speichern mußte, in denen bestimmte Resourcen in Benutzung sind/sein werden. Eine Resource darf dabei zu einem bestimmten Zeitpunkt nicht mehrfach belegt werden. Ich mußte also sicherstellen, daß sich die Zeitbereiche einer Resource nicht überlappen.

Check Constrainst von PostgreSQL alleine hilft da leider nicht. Der kann nur auf Konsistenz innerhalb eines Datensatzen prüfen, z.B. ob das Startdatum vor dem Enddatum liegt. Soll geprüft werden, ob die neu einzufügenden Daten in irgendeiner Beziehung zu bereits vorhanden Daten stehen, so müssen Regeln (RULE) definiert werden. Dies sieht in meinem Beispiel so aus.

CREATE TABLE sometable (
	id				serial,
	start_date			date		NOT NULL,
	end_date			date		NOT NULL,
	resource			integer	NOT NULL,
	CHECK (start_date<=end_date)
);
CREATE RULE no_overlap_insert AS ON INSERT TO sometable
WHERE EXISTS (
	SELECT * FROM sometable
	WHERE ((( new.start_date>=start_date AND new.start_date<=end_date )
		OR ( new.end_date>=start_date AND new.end_date<=end_date ))
	  AND new.resource=resource)
)
DO INSTEAD NOTHING;

Hier habe ich also ein Check Constrainst, das prüft, ob das Startdatum auch wirklich vor dem Enddatum liegt sowie eine Regel, die verhindert, daß ich eine Resource zu einer Zeit mehrfach belege.

Unschön an dieser Lösung ist jedoch, daß der Check Constrainst einen Fehler hervorruft, wenn die Bedingung nicht erfüllt wird, während die Regel einfach still die Daten verwirft. Man kann also nur anhand der Anzahl der geänderten Datensätze, die nach jedem INSERT/UPDATE zurückgegeben wird, feststellen, ob die Daten erfolgreich gespeichert wurden. Hier wäre es natürlich angenehmer, wenn auch ein Fehler erzeugt würde.

Nicht im Beispiel enthalten ist eine zweite Regel, die verhindert, daß man bereits vorhandene Datensätze so ändert, daß es doch wieder zu Überlappungen kommt. Hierzu muß einfach eine zweite Regel (mit anderem Namen) erstellt werden, die statt ON INSERT ein ON UPDATE enthält.

Eingetragen von FastJack am 7. Juni 2006 um 18:42

PostgreSQL auf Mac OS X selbstgebaut

Stichwörter: anleitung, apple, installation, kompilieren, launchd, mac, macosx, postgresql, sql

Dies ist eine Anleitung, um PostgreSQL auf Mac OS X Tiger zu installieren. Diese Anleitung ist größtenteils an diese Anleitung angelehnt, doch an einigen Stellen weiche ich davon ab, wo es mir sinnvoll erschien. Ich habe sie für mich und meinen Arbeitskollegen geschrieben, doch ich hoffe, daß sie sich auch für andere als hilfreich erweist.

Es gibt viele Anleitungen, die beschreiben, wie man PostgreSQL auf einem Unix-System installiert. Mac OS X ist im Grunde ein solches. Doch es bringt ein zusätzliches Verzeichnis-Layout mit sich, was sich hierfür eher anbietet. Nach der Installation befinden sich alle Dateien von PostgreSQL in /Library/PostgreSQL. Zusätzlich werden die Binaries sowie die Man-Pages nach /usr/local symlinked, damit man diese einfach von der Kommandozeile benutzen kann. (/usr/local/bin werden die meisten im $PATH haben). Zum Schluß landen die Datenbanken selbst in /Users/Shared/PostgreSQL. Alle Schritte wurden auf einem Powerbook mit G4-Prozessor durchgeführt, sollten jedoch auf den neuen Intel-Macs genauso funktionieren.

Die folgenden Schritte setzen voraus, daß Xcode auf dem System installiert ist. Ansonsten wird es schwierig, PostgreSQL zu kompilieren.

mehr…

Eingetragen von FastJack am 3. Mai 2006 um 10:27

Mit Array in PostgreSQL herumhantieren

Stichwörter: array, postgresql, sql

Ich brauchte bei einer Abfrage einfach nur die beteiligten Mitarbeiter. Eine einfache Auflistung der Namen reichte mir da. Mit PostgreSQL kann man sowas recht einfach erledigen.

SELECT array_to_string(ARRAY['foo', 'bar', 'baz', 'qux'], ', ');
  array_to_string   
--------------------
 foo, bar, baz, qux
(1 row)

Das Array wird als String mit jeweils dem zweiten Parameter aus array_to_string() verkettet. Ist viel einfacher als in der Skriptsprache (PHP, Ruby, Perl) die Rows miteinander zu verketten.

Nachtrag: Und bevor jetzt einer fragt, wie das nun mit Rows aus einer Abfrage geht, hier ein Beispiel. Ich habe diese Tabelle

test=# SELECT * from test_table;
 id | some_string 
----+-------------
  1 | foo
  2 | bar
  3 | baz
  4 | qux
(4 rows)

Und nun zu einer Row verkettet:

test=# SELECT array_to_string(ARRAY(SELECT some_string FROM test_table WHERE id<4), ', ');
 array_to_string 
-----------------
 foo, bar, baz
(1 row)

Eingetragen von FastJack am 10. April 2006 um 14:22

Notiz an mich selbst: PostgreSQL ACLs

Stichwörter: acl, grant, postgresql, sequence, sequenz, sql

Damit ein Benutzer auf eine Tabelle zugreifen darf, muß ihm dieses privileg erst eingeräumt werden. Soweit nix neues. Allerdings sollte man bei PostgreSQL nicht vergessen dem User auch Rechte auf etwaige Sequenzen zu geben, sonst schlägt ein nextval(footable_id_seq) fehl und damit der ganze Insert. Also immer schön ein GRANT SELECT, UPDATE ON footable_id_seq TO foouser; nachschieben.

(Das UPDATE ist nötig, damit beim nextval die Sequenz auch hochgezählt wird.)

Eingetragen von FastJack am 9. März 2006 um 11:52

PostgreSQL auf Mac OS X

Stichwörter: apple, installieren, kompilieren, mac, macosx, postgresql

Mein Fetisch für PostgreSQL dürfte nun kein Geheimnis mehr sein. Und auch die Installation von PostgreSQL auf Mac OS X ist dank der Pakete von Marc Liyanage sowie der Anleitung von Key Value Coding auch relativ einfach. Doch ich wollte eine noch einfachere Installation. Das Ergebnis war dieses Paket von PostgreSQL 8.1.2 (6,15MB). (Es ist inzwischen veraltet und nicht wirklich ausgiebig getestet. Bitte nicht benutzen. Es ist nur aus nostalgischen Gründen noch hier)

Das in diesem Paket enthaltene PostgreSQL habe ich größtenteils nach der Anleitung von KeyValueCoding gebaut. Der Unterschied ist liegt im Layout der Dateien im Paket sowie den Skripten, die einige Nacharbeit übernehmen, um PostgreSQL in einem lauffähigen Zustand zu hinterlassen.

mehr…

Eingetragen von FastJack am 23. Februar 2006 um 22:38

Rechnen mit Datumswerten in PostgreSQL

Stichwörter: datum, postgresql, rechnen, sql

Damit ich es nicht vergesse, und damit auch die Nachwelt was davon hat, hier ein Beispiel, wie einfach das Rechnen mit Datumswerten in PostgreSQL gehen kann.

SELECT CAST('2006-01-01 00:00:00' AS TIMESTAMP) + 5.75 * INTERVAL '1 hour'

Nachdem ich mich zuvor mit DATE_ADD und DATE_SUB bei MySQL herumgeschlagen habe, war das eine angenehme Abwechslung.

Eingetragen von FastJack am 8. Februar 2006 um 17:29

PostgreSQL auf OpenBSD

Stichwörter: bsd, datenbank, howto, installation, openbsd, postgresql, sql

Für die Installation von Movable Type auf OpenBSD brauchte ich eine Datenbank. Die Wahl fiel auf PostgreSQL. Hier ist was ich tat, um PostgreSQL nach meinen Vorstellungen zu konfigurieren.

mehr…

Eingetragen von FastJack am 23. April 2004 um 20:22