Eigenes Werkzeug · Beleg zu Daten & Prozesse
Von der API bis zur Prüfabfrage
189 Gehölzarten, 378 Bilder, eine fremde Datenquelle. Ein Python-Programm holt zu jeder Art zwei lizenzierte Fotos von iNaturalist und schreibt zu jedem Bild einen Metadatensatz. Aus diesen Metadaten entsteht hier eine kleine Datenbank – und acht Abfragen, die prüfen, ob der Bestand hält, was er verspricht. Eine davon findet etwas.
Der Anlass war unspektakulär: eine Lernkartensammlung zur Gehölzkunde, 189 botanische Namen in einem Anki-Deck, ohne Bilder. Bilder von Hand zu suchen hätte für jede Art zwei Entscheidungen gebraucht – welche Beobachtung, welches Foto – und bei 189 Arten wären das 378 Entscheidungen nach einem Bauchgefühl gewesen, das sich hinterher niemand mehr erklären kann.
Also wurden die Kriterien zuerst aufgeschrieben und dann in Code gefasst: Die Art muss exakt getroffen sein, die Beobachtung soll Research Grade haben, das Bild eine Mindestkantenlänge von 500 px, die Lizenz muss verwertbar sein – und die beiden Bilder einer Art dürfen nicht aus derselben Beobachtung stammen, sonst zeigen sie dieselbe Pflanze am selben Tag.
Das ist eine Datenpipeline. Es ist noch keine Datenbank. Die Metadaten lagen als CSV und JSON nebeneinander, ohne Schlüssel, ohne Beziehungen und ohne eine einzige Abfrage, die eine Aussage über ihre Qualität erzwingt. Diese Schicht ist 2026 nachträglich für dieses Portfolio entstanden – vier Tabellen in SQLite, acht Prüfabfragen, ein Bericht.
Der interessante Teil ist nicht, dass die Abfragen laufen. Der interessante Teil ist, dass eine davon einen Befund liefert – und dass dieser Befund nicht weggeräumt wurde.
Was davon meine Arbeit ist
- Das Python-Programm – Konfiguration, API-Anbindung, Namensauflösung, Bewertung der Kandidaten, Download, Berichte. 12 Module, rund 2.300 Zeilen.
- Die Datenbank und die Abfragen – Datenmodell, Import, acht Prüfungen, Prüfbericht. Nachträglich, 2026.
- Nicht von mir – sämtliche Bilder und alle Inhalte der Metadatensätze. Sie stammen von iNaturalist-Nutzer:innen und stehen unter fünf verschiedenen Creative-Commons-Lizenzen.
Anlass war eine private Lernkartensammlung, kein Auftrag. Der User-Agent des Programms sagt das auch der API.
Auf einen Blick
- 189 Arten · 378 Metadatensätze · 378 Beobachtungen
- 396 API-Anfragen, keine einzige Abweisung wegen Überlastung
- 376 von 378 Fotos mit Research Grade
- 378 von 378 mit Lizenzangabe: cc0 136, cc-by 214, cc-by-nc 26, cc-by-sa 2
- 8 Prüfabfragen: 6 bestanden, 1 Befund, 1 zählt
- 45 Regeltests, alle bestanden
Der Datenweg
.apkg-Datei – mit zipfile und sqlite3 der Standardbibliothek. Das Deck wird nur gelesen, nie verändert.
/v1/taxa, von spezifisch nach allgemein. Ein reiner Gattungstreffer gilt nicht als Erfolg.
/v1/observations, jedes Foto nach sieben Kriterien bepunktet. Ohne Lizenz kein Download.
Schritte 1 bis 4 sind das Originalprogramm, Stand des Laufs: 30. August 2026. Schritt 5 ist die Ergänzung für dieses Portfolio. Beide Teile sind getrennt gehalten – der Originalcode wurde nicht angefasst.
Wie ein Bild ausgewählt wird
Die Auswahl ist ausdrücklich nicht „die ersten zwei Treffer". Jedes Foto bekommt Punkte, und jeder Punkt trägt seine Begründung mit in den Bericht. Die Reihenfolge der Kriterien ist die eigentliche Entscheidung – sie legt fest, was was überstimmt.
| Kriterium | Punkte | Warum |
|---|---|---|
| Taxon identisch | +40 | Ein anderes Taxon zeigt womöglich eine andere Art. |
| Research Grade | +35 | Mehrere Personen haben die Bestimmung bestätigt. |
| Lizenz | +15 bis +30 | Freiere Lizenz ist besser: cc0 vor cc-by vor cc-by-sa vor cc-by-nc. |
| Kurze Kante ab 1.500 px | +20 | Auflösung, gestaffelt bis hinunter zur Mindestkante. |
| Abweichendes Taxon | −15 | Abwertung, kein Ausschluss – der Bericht führt es als Problemfall. |
| Kurze Kante unter 500 px | −25 | Für eine Lernkarte unbrauchbar. |
| Seitenverhältnis über 3:1 | −10 | Deutet auf Panorama oder engen Ausschnitt hin. |
| Keine Lizenzangabe | −1000 | Ausschluss. „Alle Rechte vorbehalten" wird nie stillschweigend übernommen. |
Danach kommt die Regel, die im Bericht am häufigsten sichtbar wird: Erst wird je Beobachtung das beste Foto genommen, und nur wenn keine zweite Beobachtung übrig bleibt, ein zweites Foto derselben. Deshalb stammen bei allen 189 Arten die beiden Bilder aus verschiedenen Beobachtungen – Prüfabfrage 7 rechnet das nach.
Gegenüber der API verhält sich das Programm zurückhaltend: eine Sekunde Pause zwischen zwei Anfragen, höchstens 50 pro Minute bei erlaubten 60, vier Versuche mit wachsender Wartezeit. Im dokumentierten Lauf kam über 396 Anfragen keine einzige Abweisung wegen Überlastung zurück.
Das Datenmodell
Vier Tabellen. Was in den Quelldaten nicht vorkommt, steht auch nicht im Modell: Ein Anki-Deck mit botanischen Namen kennt keinen deutschen Trivialnamen, und welche Suchvariante am Ende gegriffen hat, hält kein Metadatensatz fest. Zwei leere Spalten mitzuführen wäre die unehrlichere Lösung gewesen.
| Tabelle | Zeilen | Felder |
|---|---|---|
| plants Artenstamm |
189 | plant_id, scientific_name (Name im Deck), name_kern, taxon_id, taxon_name (Name bei iNaturalist), taxon_kern, name_abweichung |
| observations Beobachtungen |
378 | observation_id, plant_id, source, observed_on, quality_grade, place_guess, source_url |
| images Bildmetadaten |
378 | image_id, observation_id, plant_id, selected_rank, filename, url, license_code, author, attribution, width, height, sha256, file_present |
| checks Prüfergebnisse |
8 | check_id, check_type, frage, sql, expected, actual, status, note |
Der Import ist wiederholbar und nicht additiv: Ein zweiter Lauf legt die
Datei neu an, statt Zeilen zu verdoppeln. Fehlende Werte bleiben
NULL – nichts wird stillschweigend ersetzt, denn genau
diese Lücken sollen die Abfragen ja finden.
Dass die Tabelle observations genauso viele Zeilen hat wie
images, ist kein Modellierungsfehler, sondern das Ergebnis
der Auswahlregel: Weil je Bild eine eigene Beobachtung gewählt wurde,
steht hinter jedem Bild genau eine. Ein Modell, das das nicht
abbilden könnte, könnte Prüfabfrage 7 nicht stellen.
Die acht Prüfabfragen
Jede Abfrage hat einen Sollwert. Bestanden heißt: Die Abfrage findet nichts. Befund heißt: Sie findet etwas – und das ist dann das Ergebnis, kein Fehler des Programms.
| Nr. | Prüfung | Frage | Ergebnis |
|---|---|---|---|
| 1 | Abdeckung | Welche Pflanzen haben weniger als zwei ausgewählte Bilder? | 0 – bestanden |
| 2 | Dubletten | Welche Bild-URLs kommen mehrfach vor? | 0 – bestanden |
| 3 | Nachvollziehbarkeit | Welche Bilder haben keine Quell-ID oder keine Quell-URL? | 0 – bestanden |
| 4 | Lizenz | Welche Bilder tragen keine verwertbare Lizenzangabe? | 0 – bestanden |
| 5 | Nutzbarkeit | Welche Bilder unterschreiten 500 px Mindestkantenlänge? | 0 – bestanden |
| 6 | Ablage | Zu welchen Metadatensätzen fehlt die Bilddatei im Ordner? | 6 – Befund |
| 7 | Plausibilität | Stammen die beiden Bilder einer Art aus verschiedenen Beobachtungen? | 0 – bestanden |
| 8 | Taxonomie | Bei welchen Arten steht hinter dem abweichenden Namen ein anderer Artbegriff? | 21 – gezählt |
Der Befund: sechs fehlende Dateien
Der Download-Bericht des Programms meldet 378 Bilder vorhanden, Ziel 378. Im Bildordner liegen aber 372 Dateien. Die Abfrage, die Metadaten gegen Dateibestand hält, benennt die Differenz:
SELECT i.filename, p.scientific_name, i.license_code
FROM images i
JOIN plants p ON p.plant_id = i.plant_id
WHERE i.file_present = 0
ORDER BY p.scientific_name, i.selected_rank
| filename | scientific_name | license_code |
|---|---|---|
Lonicera_pileata_1.jpg | Lonicera pileata* | cc-by |
Lonicera_pileata_2.jpg | Lonicera pileata* | cc-by |
Spiraea_x_arguta_1.jpg | Spiraea × arguta | cc0 |
Spiraea_x_arguta_2.jpg | Spiraea × arguta | cc-by |
Spiraea_x_vanhouttei_1.jpg | Spiraea × vanhouttei | cc0 |
Spiraea_x_vanhouttei_2.jpg | Spiraea × vanhouttei | cc0 |
Es sind nicht sechs beliebige Dateien. Es sind genau die Bilder der drei
Arten, die das Programm im Problembericht selbst als REVIEW
markiert hat. Spiraea × arguta und
Spiraea × vanhouttei fallen bei iNaturalist auf
dasselbe Taxon zusammen – ohne Gegenmaßnahme hätten beide
Arten identische Fotos bekommen. Das Programm hat das nach dem
Durchlauf erkannt, für die zweite Art auf Ersatzfotos ausgewichen und
beide Fälle zur Prüfung vorgelegt. Lonicera pileata* wurde
auf das breitere Taxon Lonicera ligustrina aufgelöst.
Warum der Befund stehen bleibt
Es wäre in zwei Minuten erledigt gewesen: Datensätze löschen, Abfrage grün, acht von acht. Nur wäre dann eine Prüfung verschwunden, die genau das gefunden hat, wofür sie da ist. Der Zustand ist nachvollziehbar – jemand hat die drei fraglichen Arten aussortiert, ohne die Metadaten mitzunehmen. Eine Datenqualitätsprüfung, deren Befunde man wegräumt, prüft nichts mehr.
Die achte Abfrage zählt, statt zu urteilen
Bei 36 der 189 Arten weicht der Name bei iNaturalist vom Namen im Deck
ab. Als Zahl ist das wertlos: Bei 15 davon ist es nur die Schreibweise –
das Deck führt Prunus avium* mit einer Merkhilfe, iNaturalist
schreibt Prunus avium. Solche Zusätze werden vor dem Vergleich
gestrichen, in SQL wie in der Browserfassung nach derselben Regel.
Übrig bleiben 21 Fälle, in denen der Name selbst ein anderer ist. Auch diese sind nicht gleichartig, und genau deshalb bewertet die Abfrage sie nicht:
| Beispiel | Was dahintersteckt |
|---|---|
Euonymus europaea → Euonymus europaeus | Grammatische Endung. Dieselbe Art. |
Sorbus aria → Aria edulis | Gültige taxonomische Revision, andere Gattung. |
Mahonia aquifolium → Berberis aquifolium | Ebenso – der gebräuchliche Name ist heute ein Synonym. |
Hydrangea arborescens ssp. arborescens → Hydrangea arborescens | Unterart auf Art zusammengezogen. Bilder zeigen möglicherweise eine andere Unterart. |
Lonicera pileata* → Lonicera ligustrina | Auf ein breiteres Taxon aufgelöst. Fachlich zu prüfen. |
Die ersten drei Zeilen sind unbedenklich, die letzten beiden nicht – und diesen Unterschied kann keine SQL-Abfrage entscheiden. Sie kann nur die Liste erzeugen, die jemand ansehen muss. Deshalb hat Abfrage 8 als einzige keinen Sollwert und den Status gezählt statt bestanden. Eine Prüfung, die hier ein Urteil fällte, wäre genau die Sorte Automatisierung, die hinterher niemand mehr auffängt.
Zweiter Fall: eine Rechtsdatenbank
Dieselbe Arbeitsweise an einer ganz anderen Datenbank. Das Rechtsinformationssystem des Bundes (RIS) führt österreichisches Recht mit Fassungsständen. Wer daraus ohne Fassungsangabe zitiert, zitiert möglicherweise aufgehobenes Recht – und merkt es nicht.
Die Frage kam aus einem eigenen Studienprojekt. Das Detailkonzept zum Wienerberg bezeichnet das Gebiet als Landschaftsschutzgebiet, ohne eine Rechtsquelle zu nennen. Auf welcher Grundlage steht dieser Schutz, und welche Fassung gilt heute?
Abgefragt wurde die offene OGD-Schnittstelle des Bundeskanzleramts in vier Schritten: erst die Ermächtigungsnorm im Wiener Naturschutzgesetz, dann die Suche nach Verordnungen zum Stichwort Wienerberg, dann die geltende Fassung, zuletzt die Frage nach der älteren Verordnung.
Der letzte Schritt ist der, den man leicht überspringt – und der hier das Ergebnis umdreht.
Die Recherchekette
- § 24 Wr. NSchG kennt zwei Wege ins Landschaftsschutzgebiet: über eine Verordnung (Abs. 1) oder unmittelbar kraft Gesetzes für Flächen, die 1985 als Wald- und Wiesengürtel gewidmet waren (Abs. 4).
- Suchwort „Wienerberg" liefert 21 Dokumente aus Wien, aus zehn Rechtsvorschriften.
- Zwei davon betreffen die Fläche unmittelbar – und eine hebt die andere auf.
Das Ergebnis
Die Verordnung „Geschützter Landschaftsteil Wienerberg", LGBl. für Wien Nr. 46/1995, ist seit dem 9. Mai 2015 außer Kraft. § 10 der Verordnung „Landschaftsschutzgebiet Favoriten" hebt sie ausdrücklich auf und widerruft zugleich den Schutz aller Flächen des 10. Bezirks, die in den neuen Plänen nicht mehr ausgewiesen sind.
Geltende Grundlage ist damit die Verordnung Landschaftsschutzgebiet Favoriten, LGBl. für Wien Nr. 20/2015, zuletzt geändert durch LGBl. Nr. 36/2024; § 1 in der Fassung seit 23. November 2024 (Dokumentnummer LWI40016955). Ermächtigungsnorm ist § 24 Abs. 1 Wiener Naturschutzgesetz, LGBl. Nr. 45/1998. Abfragedatum: 1. September 2026.
Was aus dieser Quelle nicht folgt
Ob eine bestimmte Fläche am Wienerberg im Schutzgebiet liegt, sagt das RIS nicht. § 1 der Verordnung bestimmt den Geltungsbereich ausschließlich über die Pläne in den Anlagen – über eine ununterbrochene rote Linie. Keine Grundstücksnummern, keine Koordinaten. Für eine flächenscharfe Aussage müsste der Plan der jeweiligen Anlage mit dem konkreten Grundstück abgeglichen werden. Das ist hier nicht geschehen und wird deshalb auch nicht behauptet.
Das Protokoll ist ein Skript, kein Text: Derselbe Aufruf fragt dieselben Dokumente erneut ab. Kommt ein anderer Fassungsstand zurück, hat sich die Rechtslage geändert – genau dafür steht das Abfragedatum im Kopf der Datei.
Rechercheprotokoll (Textdatei)
Quelle: Rechtsinformationssystem des Bundes, OGD-Schnittstelle v2.6, data.bka.gv.at/ris/api/v2.6/. RIS-Daten stehen unter CC BY 4.0, Republik Österreich. Rechtsverbindlich ist allein der kundgemachte Text im Landesgesetzblatt, nicht die konsolidierte Fassung im RIS.
Woher die Regeln für die Rechtsrecherche stammen
Nicht aus einem Jusstudium. Sie stammen aus einem Werkzeug, das ich gebaut habe – einem Claude-Skill für österreichisches Recht, entstanden für eine Wirtschaftsrecht-Studentin an der WU Wien. Die Arbeit daran war nicht juristisch, sondern die Sorte Arbeit, die eine Fachanwendung braucht: festlegen, welche Quelle wann gilt, und absichern, dass das Werkzeug lieber schweigt als plausibel danebenliegt.
| Festlegung | Wirkung |
|---|---|
| RIS ist Primärquelle für geltendes Recht | Keine Fachdatenbank und keine Sekundärliteratur als Beleg für den Gesetzeswortlaut. |
| Sechs Recherchewege, je nach Frage | Aktuelle Norm, historische Fassung, Judikatur und Literatur laufen über verschiedene Routen. |
| Jeder Treffer trägt Fundstelle und Fassung | Ohne Dokumentnummer, Fassungsstand und Abfragedatum gilt ein Treffer als nicht verifiziert. |
| Nicht auffindbar bleibt nicht auffindbar | Kein Umformulieren zu „wahrscheinlich". Eine erfundene Geschäftszahl ist schlimmer als eine Lücke. |
| 19 Testfälle, 10 davon kritisch | Die kritischen prüfen den Halluzinationsschutz. Schlägt einer fehl, ist das Werkzeug für seinen Zweck unbrauchbar. |
Zum Skill gehört ein Bundle, das den RIS-Zugang installierbar macht.
Der Server darin ist nicht meiner: Es ist das
unveränderte npm-Paket ris-mcp-ts (MIT) von philrox /
Honeyfield-Org. Eigene Arbeit war der Vergleich von vier verfügbaren
Servern nach Lizenz, Wartungsstand und Abdeckung, die begründete
Auswahl und die Verpackung.
Grenzen dieses Belegs
- Keine Berufserfahrung mit Datenbanken. Die SQLite-Schicht ist 2026 nachträglich für dieses Portfolio entstanden. Es gibt keine berufliche Station, in der ich mit SQL gearbeitet habe, und das Originalprogramm hat keine Datenbank. Belegt ist, dass ich ein Datenmodell aufsetzen, Daten reproduzierbar importieren und Qualitätsprüfungen formulieren kann.
- 378 Datensätze sind eine kleine Datenmenge. Nichts an diesem Beleg sagt etwas über Datenmengen, Indizes, Abfrageoptimierung oder Datenbankbetrieb aus.
- Kein juristischer Beleg. Der RIS-Fall zeigt Recherche in einer Fachdatenbank mit Quellenhierarchie und Fassungsständen. Er ist keine Rechtsauskunft, keine Rechtsberatung und kein Nachweis juristischer Ausbildung oder Behördenpraxis.
- Kein Anlass war beruflich. Die Bildersammlung entstand für eigene Lernkarten, der Skill als Werkzeug für eine andere Person, der Recherchefall aus einem Studienprojekt.
- Keine Bilder zum Herunterladen. Die 618 MB Bildmaterial gehören iNaturalist-Nutzer:innen und stehen unter fünf verschiedenen Lizenzen. Weitergegeben werden nur die Metadaten – mit Autor, Lizenz und Quell-URL, denn ohne sie dürfte auch das nicht.
Zum Nachrechnen
Prüfabfragen im Browser Datenbank (SQLite, 252 KB) Prüfbericht (CSV) Metadaten (CSV, 132 KB) RIS-Protokoll (Text)
Die Datenbank lässt sich mit jedem SQLite-Werkzeug öffnen; die Tabelle
checks enthält alle acht Abfragen im Wortlaut samt
Sollwert und Ergebnis. Erzeugt werden beide Dateien von
skripte/artdaten-datenbank.py, das Rechercheprotokoll von
skripte/ris-recherche.py. Beide Skripte liegen außerhalb
des Website-Ordners und werden nicht mit ausgeliefert.
Weiterlesen
Zurück zum Einstieg für Daten und Prozesse · derselbe Umgang mit Pflanzendaten, aber mit einem Sprachmodell im Ablauf: Pflanzendatenbank und Automation · das Gebiet aus dem Rechtsfall, fachlich: Wienerberg – Feldbezug und Grenzen · Datenqualität an einem anderen Bestand: PIM-Werkzeug.