[PostNAS] Problematik bei der Variante *kill - Löschen alter Elemente
Brandt, Marvin
Marvin.Brandt at kreis-unna.de
Mi Jan 29 06:05:28 PST 2014
Hallo,
es gab in der Vergangenheit immer wieder Probleme, dass bei der Aktualisierung der PostNAS-Datenbank mit der Variante *kill immer noch alte Elemente in der Datenbank erhalten blieben.
Uns ist es konkret in mehreren Fällen aufgefallen. Dabei wurden Einträge in der Tabelle alkis_beziehungen nicht gelöscht. Dieses konnte auch nicht mehr zurückgeführt werden, sodass der derzeitige Trigger diese Daten nicht finden konnte.
Daher haben wir uns folgendes überlegt:
Zuerst haben wir eine weiter Tabelle in das Schema eingefügt. Diese Tabelle soll zum einen die Importierte Dateien protokollieren und zum anderen eine id erzeugen, die jedem Eintrag in der alkis_beziehungen zugeordnet werden. Dadurch ist zu erkennen, zu welchem Zeitpunkt eine Beziehung in diese Tabelle eingefügt wurde.
Hier das SQL zum erzeugen der Tabelle:
CREATE TABLE import
(
id serial NOT NULL,
datum timestamp without time zone,
verzeichnis text,
importart text,
CONSTRAINT import_pk PRIMARY KEY (id)
);
CREATE UNIQUE INDEX import_id ON import USING btree (id);
Bei jedem Import durch das Skript konv_batch.sh muss ein weiterer Eintrag in diese Tabelle erfolgen. Dieses geschieht über folgendes Komando in der konv_batch.sh:
echo "INSERT INTO import (datum,verzeichnis,importart) VALUES ('"$(date '+%Y-%m-%d %H:%M:%S')"','"${ORDNER}"','"${verarb}"');" | psql $con
Dieser Befehl muss in der konv_batch.sh muss vor dem Ausführen des Befehls ogr2ogr abgesetzt werden.
Damit jede Beziehung genau einem Datenimport zugeordnet werden kann, benötigt man in der alkis_beziehungen ein weiteres Datenfeld. Dieses nennen wir import_id.
Hier das SQL zum erzeugen der Tabelle alkis_beziehungen:
CREATE TABLE alkis_beziehungen (
ogc_fid serial NOT NULL,
beziehung_von character(16), --> gml_id
beziehungsart varchar, --> Liste siehe unten
beziehung_zu character(16), --> gml_id
import_id integer, --> import_id aus der Tabelle import
CONSTRAINT alkis_beziehungen_pk PRIMARY KEY (ogc_fid)
);
Wie kommt nun die richtige ID in das jeweilige Datenfeld?
Dazu muss man zuerst wissen, dass ogr2ogr bei jeder aktualisierung versucht, alle Beziehungen aus dem neu geliefertem Objekt zu importieren. Das wird uns in diesem Fall zu Vorteil.
Es muss ein weitere Trigger eingerichtet werden. Dieser wird diesmal auf die Tabelle alkis_beziehungen gehen.
Hier der SQL für den Trigger, der bei der Kill Variante zum Einsatz kommt:
CREATE TRIGGER update_import_id
BEFORE INSERT ON alkis_beziehungen
FOR EACH ROW
EXECUTE PROCEDURE get_import_id();
Die Funktion get_import_id(); sucht sich zuerst die letzte, und damit höchste id aus der Tabelle id. Bei jedem Import einer Beziehung in die alkis_beziehungen wird nun über diese Funktion die höchste import_id der neu importierten Beziehung zugeordnet.
Die Funktion sieht wie folgt aus:
CREATE OR REPLACE FUNCTION get_import_id() RETURNS TRIGGER AS $$
BEGIN
EXECUTE 'SELECT max(id) FROM import' INTO NEW.import_id;
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
Somit kann jetzt jeder Beziehung zugeordnet werden, mit welchem Import der NBA-Dateien diese Beziehung in die Datenbank geladen wurde. Wie vorher schon gesagt, versucht ogr2ogr jede Beziehung aus einer NBA-Datei in die Tabelle zu importieren. Früher wurde dieses jedoch nicht ausgeführt, da es schon genau so einen Datensatz gab. Nun wird er eingetragen, da es kleine Unterschiede gibt, nämlich die import_id.
Da jetzt natürlich doppelte Datensätze vorhanden sind, müssen alle Datensätze, die kleiner als die höchste id in der Tabelle import gelöscht werden. Aber nur für das Objekt, welches zuvor importiert wurde und nicht global für alle Datensätze.
Dazu ist der Trigger auf der delete Tabelle ebenfalls anzupassen.
In der Funktion delete_feature_kill() ist folgender Befehl hinzuzufügen:
EXECUTE 'DELETE FROM alkis_beziehungen WHERE beziehung_von = ''' || gml_id || ''' AND import_id < (SELECT max(id) FROM import)';
Der Datensatz in der Tabelle delete wird erst erzeugt, wenn alle anderen Tabellen bereits mit den Informationen gefüllt wurden.
Nun sind wirklich alle Informationen auf dem aktuellen Stand, da nur die Beziehungen, die mit dem letzten Import hinzugefügt wurden, in der Datenbank vorhanden sind.
Ich habe unsere Änderungen einmal in die Skripte aus dem aktuellen Trunk eingebaut.
Um zu sehen, welche Beziehungen gelöscht wurden, habe ich eine weitere Tabelle alkis_beziehungen_alt eingerichtet, in die alle Datensätze kopiert werden, bevor diese aus der Tabelle alkis_beziehungen gelöscht werden.
Hier noch eine Übersicht, an welchen Stellen die Änderungen in den Dateien zu finden ist:
alkis_PostNAS_schema.sql
Zeile 148 - 164 (Tabelle alkis_beziehungen)
Zeile 4498 - 4508 (Anlegen der import Tabelle)
alkis-trigger-kill.sql
Zeile 6 - 9 (Trigger für die alkis_beziehungen Tabelle)
alkis-functions.sql
Zeile 423 - 425 (Beziehungen sichern und löschen)
Zeile 822 - 828 (Funktion für den Trigger auf der Tabelle alkis_beziehungen)
konv_batch.sh
Zeile 100 - 101 (Erzeugen des Eintrages in die Import Tabelle)
Meine Änderungen vom 10.07.2013 nutze ich nicht mehr. Auch die entsprechenden Felder und Funktionen sind in unserer Datenbank entfernt worden.
Nachdem wir auf diese Lösung umgestellt haben, hatten wir keine Probleme mehr mit alten Einträgen.
Mit freundlichen Grüßen
Im Auftrag
Marvin Brandt
Kreis Unna - Der Landrat
Zentrale Datenverarbeitung
DV-Verfahren
Friedrich-Ebert-Straße 17
59425 Unna
Fon 0 23 03 / 27-14 16
Fax 0 23 03 / 27-28 96
marvin.brandt at kreis-unna.de <mailto:marvin.brandt at kreis-unna.de>
www.kreis-unna.de <http://www.kreis-unna.de/>
Denken Sie an die Umwelt. Pruefen Sie deshalb bitte,
ob der Ausdruck dieser E-Mail wirklich notwendig ist.
Diese E-Mail wurde beim Ausgang auf Viren geprueft. Wegen der
potentiellen Gefahr auf den Uebertragungswegen wird zu einer
Vireneingangskontrolle geraten. Eine Haftung für Virenfreiheit
wird ausgeschlossen.
-------------- nächster Teil --------------
Ein Dateianhang mit HTML-Daten wurde abgetrennt...
URL: <http://lists.osgeo.org/pipermail/nas/attachments/20140129/4f9e85b6/attachment-0001.html>
-------------- nächster Teil --------------
Ein Dateianhang mit Binärdaten wurde abgetrennt...
Dateiname : alkis_PostNAS_schema.sql
Dateityp : application/octet-stream
Dateigröße : 198873 bytes
Beschreibung: alkis_PostNAS_schema.sql
URL : <http://lists.osgeo.org/pipermail/nas/attachments/20140129/4f9e85b6/attachment-0004.obj>
-------------- nächster Teil --------------
Ein Dateianhang mit Binärdaten wurde abgetrennt...
Dateiname : alkis-functions.sql
Dateityp : application/octet-stream
Dateigröße : 53061 bytes
Beschreibung: alkis-functions.sql
URL : <http://lists.osgeo.org/pipermail/nas/attachments/20140129/4f9e85b6/attachment-0005.obj>
-------------- nächster Teil --------------
Ein Dateianhang mit Binärdaten wurde abgetrennt...
Dateiname : alkis-trigger-kill.sql
Dateityp : application/octet-stream
Dateigröße : 238 bytes
Beschreibung: alkis-trigger-kill.sql
URL : <http://lists.osgeo.org/pipermail/nas/attachments/20140129/4f9e85b6/attachment-0006.obj>
-------------- nächster Teil --------------
Ein Dateianhang mit Binärdaten wurde abgetrennt...
Dateiname : konv_batch.sh
Dateityp : application/octet-stream
Dateigröße : 6419 bytes
Beschreibung: konv_batch.sh
URL : <http://lists.osgeo.org/pipermail/nas/attachments/20140129/4f9e85b6/attachment-0007.obj>
More information about the NAS
mailing list