1. 1. Administration
  2. Funktionalität des PgVersion Plugins
  3. Umsetzung als PgVersion Plugin in QGIS
  4. Tipps für die Praxis:

1. Administration

Dieser Abschnitt befasst sich mit der Installation und Administration der Datenbank als Vorbereitung für die Arbeit mit PGVersion.

1.1 Installation der Datenbank

Als Beispiel nehmen wir an, dass die Datenbank historisierung heißt und vom Standard-Administrator postgres auf dem Server mit der IP-Adresse 192.168.2.10 installiert werden soll.
CreateDatabase_de
Abbildung 1: Erstellen einer neuen Datenbank mit PgAdmin3.

createdb -U postgres -h 192.168.2.10 historisierung

1.1.1 Login-Rollen

Zum Testen werden zwei Login-Rollen (nutzer1 und nutzer2) für die Datenbank erstellt. Dies kann entweder über das Administrations-Tool PgAdmin3 stattfinden. Zur Vereinfachung sind Benutzername und Passwort identisch.

Oder unter Linux in der Bash ausgeführt werden.

createuser -U postgres -h 192.168.2.10 -S -D -R -e nutzer1 -W
createuser -U postgres -h 192.168.2.10 -S -D -R -e nutzer2 -W

1.1.2 Authentifizierung an der Datenbank

Die Konfigurationsdatei zur Authentifizierung pg_hba.conf muss den Erfordernissen der Nutzerumgebung angepasst werden. Es werden Einträge für gültige IP-Adressbereiche und zur Authentifizierung hinzugefügt.

Weitere Informationen finden Sie in der Hilfe des PostgreSQL-Projektes: https://www.postgresql.org/docs/9.6/static/auth-pg-hba-conf.html

1.1.3 Konfiguration der Datenbank

Es erfolgt nun die Anpassung PostgeSQL Konfigurationsdatei postgresql.conf. Es gibt hier eine Vielzahl von Einstellungsmöglichkeiten. Notwendig sind für den Beginn aber nur die Parameter port und listen_addresses. Diese gewähren den Datenbankzugriff über das Netzwerk. Daher ändern wir den folgenden Eintrag:

listen_addresses = '*'
port = 5432

Alle weiteren Parameter belassen wir an dieser Stelle wie sie sind.

1.1.4 Aktivieren der PostGIS Erweiterung für die Datenbank

Um räumliche Funktionalität in PostgreSQL nutzen zu können, muss die Datenbank um die PostGIS Erweiterungen ergänzt werden. Dies kann entweder über das Administrations-Tool PgAdmin3 stattfinden oder unter Linux in der Bash ausgeführt werden.
InstallPostGISExtension_de
Abbildung 2: PostGIS Erweiterung installieren.

Erweiterung um GIS-Funktionen nach Anmeldung an der Datenbank mit dem Befehl: psql -U postgres -h 192.168.2.10 historisierung

historisierung=# CREATE EXTENSION postgis;

1.2 Installation des QGIS Plugins PgVersion

PgVersion steht als Plugin über das QGIS Plugin-Repository zur Verfügung und kann dadurch einfach über den QGIS Plugin Manager installiert werden.

Nach der Installation liegt es im Arbeitsverzeichnis des Benutzers.

unter Linux:
/home/<benutzer>/.local/share/QGIS/QGIS3/profiles/default/python/plugins/pgversion/

unter Windows:
C:\Users\<benutzer>\AppData\Roaming\QGIS\QGIS3\profiles\default\python/plugins/pgversion/

1.3 Installation von PgVersion

Die Erweiterung der Datenbank mit den pgvs-Funktionen von PgVersion wird normalerweise von einem Rechner aus gestartet, auf dem das entsprechende QGIS Plugin „pgversion“ installiert ist. Es gibt dabei die Möglichkeit es über die Kommandozeile oder das Plugin zu installieren.

1.3.1 Installation über die Kommandozeile

Wechseln Sie in das docs Verzeichnis des Plugins.

unter Linux:
/home/<benutzer>/.local/share/QGIS/QGIS3/profiles/default/python/plugins/pgversion/docs/

unter Windows:
C:\Users\<benutzer>\AppData\Roaming\QGIS\QGIS3\profiles\default\python/plugins/pgversion/docs/

Führen Sie folgenden Befehl über die Kommandozeile aus psql -U postgres -d historisierung -h 192.168.2.10 -f create_pgversion_schema.sql

Damit wird ein neues Schema versions in der Datenbank historisierung angelegt, in das die neuen pgvs-Funktionen abgelegt sind.

Die Funktionen können grundsätzlich auch direkt auf der Datenbank ausgeführt werden. Das bedeutet, dass PgVersion auch ohne QGIS bzw. das QGIS-Plugin verwendet werden kann.

Desweiteren wird eine neue Gruppenrolle versions angelegt. Diese enthält bereits eine Reihe von Rechten, damit Login-Rollen, die Mitglied der Gruppenrolle versions sind, mit PgVersion arbeiten können.

1.3.2 Installation mit dem QGIS Plugin

Die andere Möglichkeit besteht darin, die Installation der pgvs-Funktionen in QGIS über das geladene Plugin durchzuführen. Wenn Sie einige Layer in die neue Datenbank importiert haben und mit der Historisierung des ersten Layers beginnen möchten, klicken Sie auf das Icon. Dann kommt dazu die Meldung.
Install_pgvs_de
Abbildung 4: PgVs ist nicht installiert.

Klicken Sie nun auf das Icon Install pgvs, um die Versionierung zu installieren. Danach sollte eine Erfolgsmeldung erscheinen.

Install_pgvs_success_de
Abbildung 5: Die Installation von PgVs war erfolgreich.

1.3.3 Rechtemanagement

Bevor nun damit begonnen wird, erste Layer zu versionieren, sollten ein paar DEFAULT PRIVILEGES ergänzt werden. Dazu kann z.B. wieder PgAdmin3, der QGIS DB Manager oder die Kommandozeile genutzt werden. Je nach Bedarf können die Rechte angepasst werden – hier ein Beispiel:

Rollen nutzer1 und nutzer2 werden Mitglied der Gruppenrolle versions
GRANT versions TO nutzer1;
GRANT versions TO nutzer2;

Default Zugriff auf zukünftige Tabellen erlauben
ALTER DEFAULT PRIVILEGES IN SCHEMA public, versions GRANT ALL ON TABLES TO versions;

Default Rechte auf Funktionen in Schema versions geben
ALTER DEFAULT PRIVILEGES IN SCHEMA versions, public GRANT EXECUTE ON FUNCTIONS TO versions;

Default Rechte auf Sequenzen in Schemas versions und public geben
ALTER DEFAULT PRIVILEGES IN SCHEMA versions, public GRANT USAGE, SELECT ON SEQUENCES TO versions;

Wenn eine Tabelle bereits vorher versioniert wurde, können entsprechende Rechte auch nachträglich gegeben werden. Die hier angegebenen Rechte können nach Bedarf angepasst werden.

Zugriff auf bereits existierende Tabellen erlauben
GRANT ALL ON ALL TABLES IN SCHEMA public, versions TO versions;

Rechte auf alle Sequenzen in Schema public und versions geben
GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA versions, public TO versions;

Rechte auf alle Funktionen in Schemas publich und versions geben
GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA versions, public TO versions;

2. Funktionalität des PgVersion Plugins

Nachdem die Datenbank historisierung mit dem Schema versions sowie den Nutzern nutzer1 und nutzer2 erstellt worden ist können die pgvs-Funktionen über das PgVersion Pugin genutzt werden.

Nach der Installation und Aktivierung des Plugins ist die Funktionalität über Icons in der Werkzeugleiste von QGIS erreichbar:

PgVersion_Toolbar_de.png
Abbildung 6: PG Version Werkzeugleiste.

Des Weiteren gibt es den Menüeintrag „Datenbank“ → „PG Version“:

PgVersion_Integration_de
Abbildung 7: PG Version Integration in das QGIS Menü.
Jeder Benutzer der Versionierung arbeitet in seiner eigenen Sicht. Das entspricht im weitesten Sinne dem Arbeiten mit Subversion (SVN).

2.1 Enthaltene Datenbank-Funktionen

Das bei der Initialisierung erstellte Schema versions enthält alle Informationen, die notwendig sind, um die versionierten Tabellen zu verwalten. Achten Sie darauf, keine Änderungen im Schema versions durchzuführen. Dies ist alleine den pgvs-Funktionen vorbehalten.

Sie haben übrigens auch die Option, die pgvs-Umgebung in der template1 Datenbank des PostgreSQL Servers zu installieren. In diesem Fall wird jede neu erstellte Datenbank die pgvs Umgebung automatisch enthalten.

2.1.1 pgvsinit

Die pgvsinit() Funktion initialisiert die Versionierungsumgebung für einen einzelnen Layer. Der init-Befehl lautet:

select * from versions.pgvsinit('<schema>.<tabellenname>');

Die Initialisierung arbeitet in 3 Schritten:

Alle zukünftigen Änderungen, die Sie durchführen, finden auf dem View <tabellenname>_version statt. Wenn Sie die Geometrie oder den Attributwert eines versionierten PostGIS-Layers ändern möchten, können Sie dies in der gleichen Art und Weise zu tun, wie Sie eine echte Tabelle bearbeiten.

Nachdem die Änderungen für den Layer gespeichert wurden, werden sie sichtbar – aber nur für Sie. Dazu werden sie in einem temporären Zustand, als Memory Layer gespeichert. Um die Änderungen für den Rest der Welt sichtbar zu machen, müssen Sie Ihre Änderungen an die Datenbank committen.

Es ist nicht möglich, die Struktur der darunterliegenden Tabelle zu ändern. Wenn Sie dies tun wollen, müssen Sie das Versionierungssystem aus der Tabelle löschen, wie später beschrieben wird. Dann können Sie Ihre Änderungen vornehmen. Anschliessend müssen Sie wieder das Versionierungssystem für die Tabelle initialisieren.

2.1.2 pgvscommit

Wenn Ihre Änderungen nach einer Weile abgeschlossen sind, müssen Sie diese an die Master PostGIS-Tabelle übergeben (committen). Auf diese Weise stellen Sie Ihre Änderungen den anderen Benutzern zur Verfügung.

Der commit Befehl lautet:

select * from versions.psvscommit('<schema>.<tabellenname>', '<_log-Nachricht_>');

Manchmal kommt es vor, dass zwei oder mehrere Benutzer an dem selben Tabellenobjekt arbeiten. In diesem Fall listet die Funktion pgvscommit() die in Konflikt stehenden Datensätze auf. Die Konflikt-Objekte werden nicht in der Datenbank gespeichert. Bitte kontaktieren Sie in diesem Fall den anderen Benutzer in der Fehlermeldung, um zu diskutieren, welche Änderung in die Datenbank übernommen werden soll.

2.1.3 pgvsmerge

Um Konflikte zu lösen dient der Befehl:

select * from versions.pgvsmerge('<schema>.<tabellenname>',<_record-id_>,'<_Benutzername_>');

2.1.4 pgvsdrop

Die Versionierung für eine bestimmten Tabelle zu entfernen, geht mit dem Befehl: select * from versions.pgvsdrop('<tabellenname>');

Damit werden alle Versionierungseinträge aus der PostGIS-Tabelle entfernt. Sie können nur die Versionierung von einer Tabelle löschen, wenn alle Änderungen aller Nutzer committet sind.

Dabei müssen Sie keine Sorge haben, denn der Befehl pgvsdrop('<tabellenname>'); entfernt nur das Versionierungssystem. Die Master PostGIS-Tabelle mit allen ehemaligen Veränderungen (committs) existiert natürlich weiterhin.

2.1.5 pgvsrevert

Die pgvsrevert Funktion bietet die Möglichkeit, alle bis dato noch nicht committeten Änderungen zu entfernen und Ihre Daten auf die HEAD-Revision zurückzubringen. Die Revisionsnummer der HEAD-Revision wird dabei zurückgegeben.

select * from versions.pgvsrevert('<tabellenname>');

2.1.6 pgvsrevision

Die pgvsrevision Funktion gibt die installierte Revison von pgvs zurück.

select * from versions.pgvsrevision();

2.1.7 pgvslogview

Die pgvslogview Funktion gibt alle Protokolle einer bestimmten, versionierten Tabelle zurück:

select * from versions.pgpslogview ('<tabellenname>');

2.1.8 pgvsrollback

Die pgvsrollback Funktion bringt eine Revision wieder zurück auf die HEAD Revision:

select * from versions.pgvsrollback('<tabellenname>', revision integer);

Diese Funktion arbeitet zuverlässig ab der pgvs db-Version 1.8.4 und der QGIS-Plugin Version 2.0.2. Falls es vorherige Revisionen eines Layers gibt, sind diese nicht für einen Rollback bereit.

2.1.9 pgvsincrementalupdate

Die Funktion pgvsincrementalupdate bietet die Möglichkeit, einen neuen Layer, mit exakt gleicher Struktur, mit dem HEAD der Versioinierung zu vergleichen und dann die Änderungen in die Versionierung zu spielen. Es werden letztendlich dann nur noch die Unterschiede mit dem Repository abgeglichen.

select * from versions.pgvsincrementalupdate ('<import_table_name>', '<versioned_table_name>');

3. Umsetzung als PgVersion Plugin in QGIS

Um das Arbeiten mit den pgvs-Funktionen zu erleichtern, sind diese als QGIS Plugin PgVersion für QGIS 3.x und PostGIS 2.x umgesetzt. Die damit zur Verfügung stehende Funktionalität umfasst folgende Arbeitsschritte:

3.2 Layer mit dem Versionierungssystem versehen Layer_versioned_System_Icon_de

Mit dieser Option starten Sie die Versionierung für einen PostGIS-Layer. Sie haben dies einmal zu tun für jeden Layer, der in die Versionierung integriert werden soll. Wählen Sie den Layer im Layerfenster aus und klicken Sie auf das Icon „Die Ebene zur Versionierung vorbereiten“ und das Versionierungssystem wird für diesen initialisiert.
Version_Environment_de
Abbildung 8: Erstellen der Versionsumgebung.

Nachdem Sie diesen Schritt bestätigt haben, öffnet sich ein weiteres Fenster, welches die Initialisierung bestätigt und Sie darauf hinweist, bei Bedarf die Benutzerrechte für den View anzupassen und den Layer für die weitere Bearbeitung über die Funktionalität des QGIS pgversion Plugins „Laden des versionierten Layers“ zu laden.

Initialisation_success_de
Abbildung 9: Die Initialisierung war erfolgreich!

Bestätigen Sie auch diese Meldung, indem Sie auf OK klicken. Der Layer wird nun aus dem Layerfenster entfernt. Die in Kapitel 1 beschriebenen Rechte wurden dem neu versionierten Layer als DEFAULT PRIVILEGES über die Gruppenrolle versions zugewiesen.

Um mit dem versionierten Layer arbeiten zu können, müssen Sie diesen nun erneut über die Plugin-Tools laden. Je nach Rechten kann jeder Benutzer Tabellen versionieren. Wir empfehlen aber, dies der Administration der Datenbank zu überlassen.

3.3 Laden des versionierten Layers Loading_versioned_Layer_Icon_de

Jetzt können Sie über das Icon „Laden des versionierten Layers“ den entsprechenden View laden.
Versioned_system_de
Abbildung 10: PostGIS Versionierungs-System.

Wählen Sie Ihre Datenbankverbindung. Sie sehen dann die angeschlossenen Benutzer und können den versionierten Layer aus einer Liste auswählen, in QGIS laden und mit der Bearbeitung beginnen. Wenn ein versionierter Layer bereits in QGIS geladen ist, bekommen Sie eine entsprechende Meldung angezeigt.

3.4 Änderungen übergeben Commit_Changes_de

Wenn Sie Ihre Bearbeitung abgeschlossen haben, können Sie Ihre Änderungen an die Datenbank übermitteln (committen). Speichern Sie dazu als erstes die Änderungen ab. Der Layer wird dann im Layerfenster mit einem (modified) Vermerk ergänzt.

Klicken Sie nun auf das Icon „Änderungen übergeben“. Wenn keine Konflikte zwischen Ihren Änderungen und den Änderungen eines anderen Benutzers für die bearbeiteten Objekte erkannt wurden, öffnet sich ein Dialog, in den Sie eine Log-Nachricht eingeben müssen.

Description_of_modification_de
Abbildung 11: Änderungsbeschreibung.

Wenn Sie keine Nachricht eintragen, wird die unten stehende, letzte Commit-Nachricht verwendet. Es ist also nicht möglich, einen Commit ohne Commit-Nachricht durchzuführen. Bestätigen Sie diesen Dialog danach mit OK. Über das Icon „Logs anzeigen“ können Sie sich die Log-Informationen der letzten Commits anschauen.

Für den Fall, dass ein anderer Anwender ein oder mehrere Objekte, die Sie auch bearbeitet haben, geändert hat, öffnet sich ein neues Fenster, welches die Konflikte mit den anderen Änderungen anzeigt und Möglichkeit bietet, sich für die eine oder andere Version zu entscheiden.

Changes_user01_de
Abbildung 12: Anpassungen Nutzer 1.
Canges_user02_de
Abbildung 13: Anpassungen Nutzer 2.

Um die Konflikt-Varianten der Benutzer eines Objekts aus der Tabelle unter der Karte zu markieren, wählen Sie die Zeile und damit die Objektvariante eines Benutzers aus. Diese wird dann in blau hervorgehoben.

Candidates_Conflicts_de
Abbildung 14: Kandidatenliste bei Konflikten.

Für die Bereinigung von Konflikten haben Sie zwei Möglichkeiten.

3.5 Auf die HEAD Revision zurücksetzen Head_Revision_Resetting_Icon_de

Wenn Sie eine gespeicherte, aber noch nicht committete Änderung entfernen wollen, bedeutet es, dass Sie die Ansicht zurück in die HEAD-Revision versetzen müssen, also auf die Version, die Sie zu Beginn der Arbeit ausgecheckt haben.

In diesem Fall werden alle Änderungen entfernt, die bis dahin durchgeführt haben. Um diese Funktion zu nutzen, wählen Sie den entsprechenden Layer aus und klicken auf das Icon „Auf die HEAD Revision zurücksetzen“.

3.6 Unterschiede anzeigen Show_Changes_Icon_de

Differents_in_Database_HEAD_de
Abbildung 15: Unterschied lokale Anpassung und HEAD der Datenbank.
Wenn Sie eine gespeicherte, aber noch nicht committete Änderung mit der aktuellen HEAD-Revision in der Datenbank vergleichen möchten, können Sie dies mit dem Icon „Unterschiede zur HEAD Revision“ erreichen – siehe auch Kapitel 3.7.

Dabei wird ein Differenz-Layer für den gewählten Kartenausschnitt erstellt, der Ihnen mit einer grünen Linie zeigt, welche Geometrien hinzugefügt wurden und mit einer roten Linie, welche Geometrien entfernt wurden. Die Differenz-Layer sind Memory-Layer und können problemlos wieder aus dem Layerfenster gelöscht, wenn Sie sie nicht mehr brauchen.

Wenn Sie die Änderungen in der Attributtabelle vergleichen möchten, ist dies auch möglich, indem Sie mit dem QGIS Werkzeug „Objekte abfragen“ und dem Modus „Von oben nach unten“ auf das Objekt klicken. Dann werden Ihnen als Abfrageergebnisse die Attribute angezeigt, um sie visuell zu vergleichen.

3.7 Logs anzeigen Show_Logs_Icon_de

Der Logview Dialog gibt Ihnen die Möglichkeit, einen Überblick über die Änderungen eines einzelnen Layers zu erhalten. Sie sind damit auch in der Lage zurückzukehren zu einer bestimmten Revision oder einer Markierung. Der Rollback wird dann in QGIS geladen und angezeigt.
Show_Revision_Logs_de
Abbildung 16: Revision-Logs anzeigen und darstellen.

Mögliche Vorgehensweisen sind:

Set_Tags_de
Abbildung 17: Markierungen (Tags) setzen.

3.8 Löschen ausgewählter Objekte direkt in der Datenbank Delete_selected_objects_in_DB_Icon_de

Diese Funktionalität ermöglicht es, zuvor in QGIS ausgewählte Objekte eines versionierten Layers direkt auf der Datenbank zu löschen. Die QGIS eigene Funktion zum Löschen von ausgewählten Objekten hat sich als sehr langsam herausgestellt, daher wurde diese Funktionalität an dieser Stelle zusätzlich integriert. Sie kann aber nur verwendet werden, wenn der Anwender die entsprechenden Rechte auf der Datenbank besitzt.
Delete_in_DB_de
Abbildung 18: Löschen direkt in der Datenbank.

3.9 Versionierung der Ebene löschen Delete_selected_objects_in_DB_Icon_de

Diese Funktionalität ist genau wie das direkte Löschen in der Datenbank nicht direkt über die Werkzeugleiste erreichbar. Das Löschen der Versionierung eines Layers löscht nicht den Layer selbst.

Es geht dabei „nur“ um die Versionierungsumgebung des Layers. Dies ist in dem Moment notwendig, wenn Sie das Modell der Layers ändern wollen, z.B. eine neue Attributspalte hinzufügen oder keine Versionierung mehr für den Layer nutzen wollen.

Aktivieren Sie den entsprechenden Layer und klicken auf "Versionierung des Layer löschen“ im Menü.

4. Tipps für die Praxis

An dieser Stelle soll anhand praktischer Tipps der Einstieg in das Arbeiten mit dem Plugin erleichtert werden. Wir gehen dabei davon aus, dass die entsprechenden Layer bereits historisiert sind.

4.1 Grundsätzliche Einstellungen in QGIS

4.2 Historisierung eines Layers mit bigint Datentyp der ID Spalte

Bei einigen Daten ist die ID Spalte in der Attributtabelle als „bigint“ oder „Integer64“ Datentyp angelegt. Beim Import dieser Layer nach PostGIS wird der Datentyp nicht automatisch nach „bigserial“ umgewandelt. Dies ist aber notwendig für die Versionierung, wo die Spalte per Default als „Primary-Key“ Spalte fungiert. Daher muss nach dem Import und vor der Versionierung die Umwandlung vom bigint zum bigserial Datentyp manuell erfolgen, siehe Beispiel für den Layer bauleitplanung_nds.

Als erstes wird bei dem bestehenden Datensatz der nächst folgende Wert für die Spalte id ermittelt:

SELECT MAX(id)+1 FROM "bauleitplanung_nds";

Mit dem Ergebnis (z.B.: 44151) wird dann eine Sequenz erzeugt und der Spalte id zugewiesen, so dass diese dann in den serial Datentyp umgewandelt wird. Dazu sind folgende weitere Schritte notwendig:

CREATE SEQUENCE bauleitplanung_nds_id_seq start with 44151 owned by "bauleitplanung_nds"."id";

ALTER TABLE bauleitplanung_nds ALTER COLUMN id SET DEFAULT nextval('bauleitplanung_nds_id_seq');

ALTER SEQUENCE bauleitplanung_nds_id_seq OWNED BY "bauleitplanung_nds"."id";

Das PgVersion Plugin prüft bei der Initialisierung eines neuen Layers, ob der PrimaryKey Datentyp „serial“ oder „bigserial“ ist. Wenn dies nicht der Fall ist, wird der Vorgang mit einem Fehler abgebrochen.

DB_mistake_de
Abbildung 19: Fehler bei fehlendem serial Datentyp.

4.3 Anpassen vorhander Objektgeometrien eines Layers

4.4 Anpassen vorhandener Attribute eines Layers

4.5 Ein neues Objekt zu einem Layer hinzufügen

4.6 Objekte in einem Layer löschen

4.7 Aktuell durchgeführte Änderungen verwerfen

4.8 Auf eine vorherige Revision eines Layers zurückgehen

4.9 Einen Layer aus der Versionierung entfernen

4.10 Auflösen eines Konflikts bei der Bearbeitung

4.11 Aktualisieren mit copy/paste am QGIS Bildschirm

4.12 NULL Werte der Primary-Key Spalte nicht erlaubt

QGIS erkennt beim Editieren das Vorhandensein einer Primary-Key Spalte und erlaubt es dann nicht, diese ohne Eintrag eines Wertes zu speichern.
NULL_Value_in_PrimaryKey_de
Abbildung 20: Speichern eines Wertes mit einem Primary-Key NULL.

Es gibt 2 Möglichkeiten, damit umzugehen.

Save_Style_in_DB_de
Abbildung 21: Speichern des Stils in der Datenbank.