[PostNAS] alte Einträge in der alkis_beziehungen vorhanden

Jäger, Frank (KRZ) F.Jaeger at KRZ.DE
Do Jul 11 07:07:09 PDT 2013


> -----Ursprüngliche Nachricht-----
> Von: nas-bounces at lists.osgeo.org [mailto:nas-bounces at lists.osgeo.org] Im
> Auftrag von Brandt, Marvin
> Gesendet: Mittwoch, 10. Juli 2013 22:53
> An: NAS Schnittstelle via ogr2ogr
> Betreff: Re: [PostNAS] alte Einträge in der alkis_beziehungen vorhanden
> 
> Hallo zusammen,
> der Kreis Unna benutzt ebenfalls die Abgabeart 1000 stichtagsbezogen (ohne
> Historie).
> Kann es vielleicht daran liegen, dass ihr schon die Datei pp_laden.sql aus dem
> Trunk verwendet, die diese doppelten Buchungen löscht?
> Derzeit Zeile 98 - 124. Dann können auch keine doppelten Datensätze mehr
> auftauchen.
> 
> Gruß
> Marvin Brandt


Hallo Marvin,
wieso "schon"? Die Änderung ist vom 21. Februar!  Natürlich verwenden wir das. Dazu wurde es ja entwickelt.
Eigentlich ist alles was ich dort hoch lade auch produktiv im Einsatz.

In der Datei "alkis-funktions.sql" im Zweig "Replace" der Trigger-Funktion "delete_feature_kill" ist dazu dokumentiert:

-- Beziehungen des Objektes wurden redundant noch einmal eingetragen
-- ToDo:         HIER sofort die Redundanzen zum aktuellen Objekt beseitigen.
-- Workaround: Nach der Konvertierung werden im Post-Processing
--             ALLE Redundanzen mit einem SQL-Statement beseitigt.

Es folgt dann ein noch auskommentierter Entwurf einer möglichen Lösung.

Besser wäre es, das sofort nach Eintrag des "Replace" und gezielt für die betroffenen Objekte im Trigger zu beseitigen. Dann wäre die Datenbank auch während der Konvertierung konsistenter (keine Duplikate), nicht erst nach dem Laden aller Dateien und Abschluss der Nachverarbeitung.

Das Statement im Post-Processing "pp_laden.sql" und auch der Entwurf im Trigger finden sowieso nur komplette Redundanzen. Also Datensätze, die in allen 3 Feldern "beziehung_von", "beziehung_zu" und "beziehungsart" identisch sind.

Trotz Einsatz dieses Redundanz-Entferners findet dein Test-SQL ja in einer meiner Datenbanken (die aus der Abgabeart 3100) noch 8 Fälle mit mehr als einer Buchung zum Flurstück (die muss ich mir noch näher ansehen).
Das müssen komplexe Fälle sein, wo eine Buchung im Rahmen eines Replace seine Verbindung zum Flurstück wechselt, die Buchung selbst aber weiter besteht.
Das Test-SQL sucht nur nach "Buchungen", weil dazu bekannt ist, dass jedes Flurstück genau eine Buchung haben muss.
Siehe auch gespeicherter View "mehrfache_buchung_zu_fs" (Ah! Es sind nur 4 Fälle. Dein SQL liefert die IDs doppelt)
Eventuell gibt es noch Beziehungen zwischen anderen Objektarten, wie der von dir beschriebene "Tausch der Hausnummern" zwischen zwei Flurstücken, wo auch noch alte Beziehungs-Sätze übrig bleiben. Das ist schwieriger zu finden, weil es ja mehrere (0 bis N) Beziehungen zum Objekt geben darf. 

Ich teste gerade mit Produktionsdaten die von dir als mögliche Lösung gelieferte Erweiterung der Beziehungs-Tabelle und des Triggers um von-und-zu-Tabellen-Typ und beginn-Datum. Vorläufige Erkenntnisse dazu:
Der Tabellenname auf der von-Seite und somit das beginnt-Datum des von-Objektes wird immer gefüllt.
Der Tabellenname auf der zu-Seite bleibt aber in 1,3% der Fälle leer.
Ich vermute, dass eine Beziehung zusammen mit einem von-Objekt manchmal schon eingetragen wird, wenn das zu-Objekt selbst noch nicht in seine Tabelle geladen wurde. Dann kann der erweiterte Trigger zu dem Zeitpunkt, wo die Beziehung eingetragen wird, ihn dort auch noch nicht finden.

Wegen dieser Fehlerquote und auch wegen des Aufwandes, den es verursacht, alle 138 Objekt-Tabellen bei jedem Replace nach den 2 Objekten zu durchsuchen (2 * 138 * UNION), wäre es besser, wenn PostNAS (ogr2ogr) diesen Eintrag selbst setzt (das wäre eine Programm-Erweiterung).

Die von dir vorgeschlagene Trigger-Funktion bereinigt die Beziehungen zudem nur bei Replace auf der von-Seite.
"von" und "zu" sind hier aber als gleichwertig zu sehen und somit müsste auch noch auf "zu"-Seite das beginn-Datum ermittelt und für eine Bereinigung der Beziehungen verwendet werden. Dazu müsste die Tabelle aber vollständig sein.

Es ist ganz schön schwierig ....

Vorschlag für weiteres Vorgehen:

1. Einsatz aktuelles Post-Processing bei euch in Unna.
    Bzw. Ausführen des SQL hinter " Redundanzen aus alkis_beziehungen beseitigen"
   - Dann Immer noch Probleme?

2. Die Logik des Post-Processing in den Trigger verlegen
   - Siehe Datei "alkis-functions.sql" bei Zeile "-- ENTWURF ungetestet:"

3. Gibt es dann immer noch Sonderfälle, wo Beziehungen nicht passen?
  Dazu dann Testdaten aufbereiten um diese Fälle zu knacken.

Entscheidend für die Logik der Trigger ist, in welcher Reihenfolge die einzelnen Einträge erfolgen.
Das Grundübel ist, dass bei einem Replace erst die neuen Objekte zu den alten Objekten und die neuen Beziehungen zu den alten Beziehungen hinzugefügt werden. Der nachfolgende Trigger - ausgelöst durch Einfügen in der delete-Tabelle - hat dann Probleme, die zu löschenden alten Beziehungen zu identifizieren. Die "gml_id"s als Hauptschlüssel sind noch gültig und weitere eindeutige Informationen in der Beziehung-Tabelle fehlen. 
Wenn - wie oben beschrieben - ein in der Beziehung auf zu-Seite gemeintes Objekt während der Trigger-Ausführung noch nicht da ist, wird es noch schwieriger.
Dies greift sowieso nur bei Redundanzen. 
Die jetzige Logik beim Löschen der Objekte basiert auf "der Eintrag mit dem größten Serial-Feld muss der aktuelle sein". 
Die gleiche Logik wird auf den Beziehungen für redundante Zeilen verwendet.
Aber wie identifiziere ich alte Beziehungen nach einem Objekt-Wechsel auf von- oder zu-Seite?
Also: Ein Objekt wird mit replace ersetzt, es hat immer noch die gleich gml_id. In der Objekt-Tabelle wird die Version mit dem älteren Serial gelöscht.
In der Beziehungen-Tabelle stehen die Beziehungen der alten Objekt-Version und die der neuen Objekt-Version. Beide verlinkt über die gleiche gml_id.
Wie bekomme ich heraus, welches die alten sind, die zu löschen wären?

Es wäre alles bedeutend einfacher, wenn ogr2ogr zuerst das Replace in die delete-Tabelle schreiben würde, welches den Trigger feuert.
Dann könnten alle vorhandenen (zu dem Zeitpunkt nur die alten) Beziehungen vom Trigger sicher und komplett gelöscht werden. Danach würden vom Konverter die neuen Beziehungen eingefügt.
Diese Reihenfolge würde dann aber Probleme bringen, wenn man "mit Historie" arbeiten möchten (ganz andere Trigger).

Um die alten Beziehungen bei einem Replace wirklich sauber zu entfernen wäre es denkbar, diese alles entscheidende Reihenfolge über eine Option beim Lauf von ogr2ogr zu steuern, damit dies an die Bedürfnisse mit/ohne Historie angepasst werden kann. 
Das macht die Bedienung und die Einstiegs-Schwelle von PostNAS nicht leichter. Man müsste 'Option beim Programmlauf' und 'Trigger beim Anlegen der Datenbank' streng aufeinander abstimmen.

@ Bernd Kamjunke
  Asche wieder vom Haupt schütteln! Ich war auch bisher davon ausgegangen, dass die Probleme mit redundanten Beziehungen in Unna auftreten, obwohl die aktuelle (noch nicht perfekte) Lösung zum Entfernen redundanter Beziehungen eingesetzt wird. 
Wenn nur vom Konverter (redundant) eingetragen wird, aber nichts (weder Trigger noch Post-Processing) die doppelten Einträge wieder entfernt, dann ist klar, dass es Probleme gibt.

Mfg
F. Jäger


More information about the NAS mailing list