[PostNAS Suite] Fehler beim Konvertieren

Stefan Rahn stefan.rahn at gdi-service.de
Mo Mai 4 03:05:13 PDT 2020


Hallo Frank,

Ich weiß nicht, ob es was zur Lösung der doppelten Objekte beitragen 
kann aber ich wollte hier mal kurz das Konzept darstellen, wie wir beim 
Einlesen von neuen Objektversionen vorgehen.

Bei uns gibt es die Variante "kill" nicht, es wird also alles historisch 
gesetzt. Aber unabhängig davon, ob man nun löscht oder historisch setzt, 
hat man ja bei beiden Varianten das schon angesprochene Problem, dass es 
während eines Einlesevorgangs Fälle gibt, bei denen zuerst das Replace 
kommt und erst danach das Insert. Die Reihenfolge ist also vertauscht.

Ein Trigger, der beim Einlesen des Replace-Objekts durch einen Eintrag 
in die delete-Tabelle ausgelöst wird, kann aber noch gar nichts machen, 
da eben durch das fehlende Insert die Vorgängerobjektversion noch nicht 
da ist. Deswegen sind wir dazu übergegangen, das Beenden der historisch 
gewordenen Objektversionen erst ganz am Ende des Einlesevorgangs zu 
machen. Denn dann wurden auch alle Inserts eingelesen.

Das Beenden der historisch gewordenen Objektversionen erfolgt bei uns 
durch den Aufruf der Funktion "execute_hist_operations()", zu finden 
hier: [1]

Diese Funktion verwendet die Informationen aus der Tabelle "delete", um 
die Objekte zu beenden. Voraussetzung dafür ist natürlich, dass dort 
auch die richtigen Informationen drin stehen. Leider schreibt ogr2ogr 
nicht in allen Fällen die notwendigen Infos dort rein. Deswegen hängt an 
der Tabelle "delete" ein "BEFORE INSERT"-Trigger mit der 
Trigger-Funktion "log_hist_operations()" [2], die dafür sorgt, dass die 
benötigten Infos dort korrekt eingetragen werden.

Wir verwenden dieses Konzept der Fortführung in mehreren Landkreisen nun 
schon ein paar Jahre und es läuft mittlerweile sehr stabil und fehlerfrei.

[1] 
https://github.com/srahn/kvwmap/blob/kvwmap/plugins/alkis/db/postgresql/schema/2018-08-13_15-12-00_ignore_dublicates_trigger.sql 


[2] 
https://github.com/srahn/kvwmap/blob/kvwmap/plugins/alkis/db/postgresql/schema/2017-12-20_14-36-50_log_hist_operations.sql

Viele Grüße,

Stefan Rahn

-- 
  
GDI-Service
Friedrichstraße 16
18057 Rostock
Tel: 0381 40344445
E-Mail: stefan.rahn at gdi-service.de
gdi-service.de

Am 30.04.2020 um 14:13 schrieb Jäger, Frank (KRZ):
> Moin!
> ich bin einem Fehler auf der Spur, der nur unter bestimmten Bedingungen auftritt.
> Der Fehler führt zu inkonsistenten Daten aber nicht zu Meldungen beim Konvertieren, er bleibt daher zunächst unentdeckt.
>
> Die Wirkung: Die Datenbank enthält doppelte Objekte. Alte Versionen bei einem "Replace" werden nicht gelöscht.
>
> Bedingungen:
>
> Ab der Version 3.0-22 des ALKIS-Importers hat man beim Anlegen einer neuen Datenbank die Option "Historie führen".
> Auswahl "ja" ist nicht betroffen, Bei Auswahl "nein" kann der Fehler auftreten.
> Somit sind nur Sekundärbestände betroffen, die in den letzten Monaten neu angelegt wurden. Davor wurde als Standard "mit Historie" verwendet.
>
> Der Import einer Erstabgabe ist noch korrekt, weil dabei nur "Insert" vorkommen.
> Bei einer Aktualisierung kommen auch "Replace" vor, das kann dann zum Fehler führen.
>
> Daten aus dem abgebenden ALKIS der Firma "ibR" sind nicht betroffen.
> Der Fehler tritt nach meinen Beobachtungen nur auf, wenn Daten aus Software der Firma AED importiert wird. Zu Versionen kann ich nichts sagen.
>
> Wenn die gennannten Bedingungen erfüllt sind, kann man z.B. mit folgendem SQL suchen:
>
>   SELECT gml_id, count(anlass) AS anzahl FROM ax_flurstueck
>   WHERE endet IS NULL
>   GROUP BY gml_id HAVING count(anlass) > 1;
>
> Wenn diese Abfrage Zeilen liefert, dann habt ihr ein Problem. Wenn nichts zurück kommt, gibt es keine mehrfach vorkommenden Flurstücke. Der Fehler tritt aber auch in anderen Tabellen auf.
>
> Lösung: Jürgen hat bereits einen Vorschlag zur Korrektur. Ich muss das aber noch umfangreich testen mit verschiedenen Daten.
> Es wird aber wohl notwendig werden, die kaputten Datenbanken neu zu konvertieren.
> Theoretisch denkbar ist auch in allen Tabellen nach doppelten Kennzeichen zu suchen und die jeweils ältere Version zu löschen.
>
> Analyse der Fehlerursache:
>
> Jetzt wird's kompliziert!
> Das Einfügen von neuen Datensätzen in die Datenbank führt das Programm ogr2ogr direkt durch. Das Beseitigen der Vorgänger wird erledigt durch eine Trigger-Function in der PostgreSQL-Datenbank.
> Die Funktion wird "getriggert" durch das Einfügen eines Satzes in die Tabelle "delete".
> Es gibt zwei Typen von Functions. Beide sind in der Datenbank definiert, aber nur eine ist - entsprechend der Option - mit dem Trigger verbunden.
> Die eine Version setzt dem Vorgänger ein Datum in seine Spalte "endet", das Objekt wird damit "historisch", verbleibt aber in der Datenbank. Die Anwendungen müssen darauf achten, solche Objekte nicht zu verwenden, wenn eine aktuelle Auswertung benötigt wird.
> Eine andere Version des Triggers (Kill-Trigger) löscht das alte Objekt sofort aus der Datenbank statt es nur historisch zu machen.
>
> Seit dem letzten Jahr gibt es nun im abgebenden ALKIS der Firma ibR eine neue Option "NBA Modellschwäche ausgleichen". Dazu sage ich hier nichts um mich nicht zu verzetteln. Damit werden dann aber massenhaft Objekte geliefert, die schon in genau gleicher Aktualität im Sekundärbestand vorhanden sind. Der Insert von ogr2ogr scheitert am eindeutigen Index.
> Wenn dann der Kill-Trigger mit Replace ausgelöst wird, dann darf der nichts löschen, weil es keine alte Version dazu gibt. Erkannt wird das durch Vergleich des Zeitstempels alt/neu. Ist der gleich, dann wird nichts gelöscht, und das ist auch gut so.
>
> Nun gibt es eine "Besonderheit" in den NAS-Replace-Daten aus AED-ALKIS. Ich denke, das ist ein Fehler, aber das mögen andere beurteilen.
>
> In einem Replace-Block sieht das (stark vereinfacht) bei ibR so aus:
>
> <wfsext:Replace vendorId="AdV" safeToIgnore="false">
>      <AX_Flurstueck gml:id="DE[*NEUE ZEIT*]">
>          <lebenszeitintervall>
>              <AA_Lebenszeitintervall>
>                <beginnt>[*NEUE ZEIT*]</beginnt>
>           </AA_Lebenszeitintervall>
>        </lebenszeitintervall>
> ....
>        <ogc:Filter>
>            <ogc:FeatureId fid="DE[*ALTE ZEIT*]" />
>        </ogc:Filter>
> </wfsext:Replace>
>
> Merke: Vorne neue Zeit, hinten alte Zeit.
>
> Bei AED steht aber auch vorne in "<AX_Flurstueck gml:id=""  die ALTE Zeit!?
> Dies schlägt durch auf den Trigger. Der erkennt fälschlicherweise neu=alt, also Fall "Systemschwäche", also nichts löschen.
>
> In diesem Fall ist das aber nicht richtig, weil in der Datenbank zu dem Zeitpunkt zwei Versionen stehen und die ältere müsste bei "Replace" ersetzt, d.h. gelöscht werden.
>
> PS
> Es hat eine Weile gebraucht, um das heraus zu finden.
>   
> Es grüßt aus dem Home-Office
>
> Frank Jäger
>
> Kommunales Rechenzentrum
> Minden-Ravensberg/Lippe
> Tel.: 05261 / 252 - 185
> mailto:f.jaeger at krz.de
> http://www.krz.de/
>
> _______________________________________________
> NAS mailing list
> NAS at lists.osgeo.org
> https://lists.osgeo.org/mailman/listinfo/nas

-------------- nächster Teil --------------
Ein Dateianhang mit HTML-Daten wurde abgetrennt...
URL: <http://lists.osgeo.org/pipermail/nas/attachments/20200504/5950ed1e/attachment.html>


Mehr Informationen über die Mailingliste NAS