<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>CSV | FDMLab@LABW</title><link>https://fdmlab.landesarchiv-bw.de/tag/csv/</link><atom:link href="https://fdmlab.landesarchiv-bw.de/tag/csv/index.xml" rel="self" type="application/rss+xml"/><description>CSV</description><generator>Wowchemy (https://wowchemy.com)</generator><language>de-de</language><lastBuildDate>Wed, 14 May 2025 00:00:00 +0000</lastBuildDate><image><url>https://fdmlab.landesarchiv-bw.de/media/sharing.jpg</url><title>CSV</title><link>https://fdmlab.landesarchiv-bw.de/tag/csv/</link></image><item><title>Workshop - Python in OpenRefine</title><link>https://fdmlab.landesarchiv-bw.de/workshop/openrefine-fortgeschrittene/20-python-mit-openrefine/</link><pubDate>Wed, 14 May 2025 00:00:00 +0000</pubDate><guid>https://fdmlab.landesarchiv-bw.de/workshop/openrefine-fortgeschrittene/20-python-mit-openrefine/</guid><description>&lt;p>Wir verwenden Python zusammen mit OpenRefine.&lt;/p>
&lt;blockquote>
&lt;p>Jython in der &lt;a href="https://openrefine.org/docs/manual/jythonclojure#jython" target="_blank" rel="noopener">OpenRefine Dokumentation&lt;/a>.&lt;br>
Einsteiger Workshop &lt;a href="https://fdmlab.landesarchiv-bw.de/workshop/openrefine-fortgeschrittene/19-erweitertes-clustering/">19 Daten mit OpenRefine clustern&lt;/a>.&lt;br>
Blogbeitrag &lt;a href="https://fdmlab.landesarchiv-bw.de/post/2021-08-ner-mit-openrefine-und-spacy/">Named Entity Recognition mit OpenRefine und spaCy&lt;/a>.&lt;/p>
&lt;/blockquote>
&lt;div class="alert alert-note">
Dieser Workshop wurde erstellt mit OpenRefine Version 3.5.0.&lt;br>
Dieser Workshop wurde zuletzt getestet mit OpenRefine Version &lt;strong>3.9.3&lt;/strong>.
&lt;/div>
&lt;div class="alert alert-warning">
&lt;div>
Die in diesem Tutorial behandelten Funktionen sind teilweise erst verfügbar seit der Version OpenRefine &lt;strong>3.9.3&lt;/strong>.
&lt;/div>
&lt;/div>
&lt;h2 id="jython">Jython&lt;/h2>
&lt;p>Quasi überall, wo man in OpenRefine GREL-Expressions schreiben kann, kann man stattdessen auch auf Jython umstellen.
Also beispielsweise für den
&lt;a href="https://fdmlab.landesarchiv-bw.de/workshop/openrefine-einsteiger/03-transformieren/">Transformations-Dialog&lt;/a>,
&lt;a href="https://fdmlab.landesarchiv-bw.de/workshop/openrefine-fortgeschrittene/13-die-welt-der-facets/">Facets&lt;/a> oder neu auch für
&lt;a href="https://fdmlab.landesarchiv-bw.de/workshop/openrefine-fortgeschrittene/19-erweitertes-clustering/">eigene Clustering Methoden&lt;/a>.&lt;/p>
&lt;figure id="figure-bildschirmfoto-des-transformations-dialogs-mit-jython">
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="Bildschirmfoto des Transformations Dialogs mit Jython." srcset="
/workshop/openrefine-fortgeschrittene/20-python-mit-openrefine/screenshot-openrefine-transform-with-jython_hu0d55e479ad7a3691a7fe4df239345fc3_13960_8a8daaf36e58895df4e2bb5849538213.webp 400w,
/workshop/openrefine-fortgeschrittene/20-python-mit-openrefine/screenshot-openrefine-transform-with-jython_hu0d55e479ad7a3691a7fe4df239345fc3_13960_c46dff229eb7cc4e0469107a1fc091c1.webp 760w,
/workshop/openrefine-fortgeschrittene/20-python-mit-openrefine/screenshot-openrefine-transform-with-jython_hu0d55e479ad7a3691a7fe4df239345fc3_13960_1200x1200_fit_q75_h2_lanczos_3.webp 1200w"
src="https://fdmlab.landesarchiv-bw.de/workshop/openrefine-fortgeschrittene/20-python-mit-openrefine/screenshot-openrefine-transform-with-jython_hu0d55e479ad7a3691a7fe4df239345fc3_13960_8a8daaf36e58895df4e2bb5849538213.webp"
width="530"
height="162"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;figcaption data-pre="Abbildung&amp;nbsp;" data-post=":&amp;nbsp;" class="numbered">
Bildschirmfoto des Transformations Dialogs mit Jython.
&lt;/figcaption>&lt;/figure>
&lt;p>Praktisch wird das Jython-Snippet, welches man wie in Abbildung 1 gezeigt im Dialog eingibt, in eine Python-Funktion gepackt und dann von Jython ausgeführt.
Daher benötigt man im Unterschied zu GREL ein &lt;code>return&lt;/code> Statement, um anzugeben, welcher Wert zurückgegeben wird.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="k">def&lt;/span> &lt;span class="nf">some_fun_name&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">value&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">cell&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">cells&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">row&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">rowIndex&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">value1&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">value2&lt;/span>&lt;span class="p">):&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="o">...&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Das eingegebene Snippet wird quasi anstelle von &lt;code>...&lt;/code> eingesetzt.&lt;/p>
&lt;p>Zu den in &lt;a href="https://fdmlab.landesarchiv-bw.de/workshop/openrefine-fortgeschrittene/09-arbeiten-mit-grel/#variablen">GREL zur Verfügung stehenden Variablen&lt;/a> haben wir schon einiges geschrieben. Diese stehen mit Ausnahmen in Jython unter OpenRefine ebenfalls zur Verfügung.
Beispielsweise fehlt die Variable &lt;code>columnName&lt;/code> mit dem aktuellen Spaltennamen.&lt;/p>
&lt;p>&lt;a href="https://www.jython.org/" target="_blank" rel="noopener">Jython&lt;/a> selbst ist eine Java Implementierung von Python.
Das bedeutet, dass es innerhalb von Java interpretiert wird und man auch von Jython Code aus auf verfügbare Java Methoden zugreifen kann.&lt;/p>
&lt;p>Leider hat das Projekt den Sprung auf Python 3 nicht geschafft und unterstützt daher nur die Funktionalität von &lt;a href="https://docs.python.org/2.7/" target="_blank" rel="noopener">Python 2.7&lt;/a>.
Das macht auch die &lt;a href="https://github.com/OpenRefine/OpenRefine/wiki/Extending-Jython-with-pypi-modules" target="_blank" rel="noopener">Verwendung von externen Python Bibliotheken&lt;/a> innerhalb von Jython deutlich komplexer.&lt;/p>
&lt;p>Es gibt nur noch selten Python Bibliotheken, die Python 2.7 unterstützen.
Und es können auch nur Python Bibliotheken verwendet werden, die komplett in Python geschrieben wurden.
Einige gerade sehr beliebte Python Projekte verwenden aus Performance Gründen unter der Haube kompilierte Programmiersprachen wie &lt;a href="https://www.c-language.org/" target="_blank" rel="noopener">C&lt;/a>, &lt;a href="https://fortran-lang.org/" target="_blank" rel="noopener">Fortran&lt;/a> oder &lt;a href="https://www.rust-lang.org/" target="_blank" rel="noopener">Rust&lt;/a>.
Diese können unter Jython &lt;strong>nicht&lt;/strong> direkt verwendet werden.&lt;/p>
&lt;p>Praktisch ist die Ausführung von Jython Code in OpenRefine auch deutlich langsamer, als z.B. GREL oder Clojure Code.
Das macht es eher schwierig komplexere Algorithmen z.B. für das Clustering direkt zu hinterlegen.&lt;/p>
&lt;p>Alternativ kann von OpenRefine aus, via Jython auf externen Python Code zugegriffen werden, was im folgenden Teil vertieft wird.&lt;/p>
&lt;h2 id="python">Python&lt;/h2>
&lt;h3 id="standard-setup">Standard Setup&lt;/h3>
&lt;p>Wir verfolgen die Idee von OpenRefine aus auf Python Code zuzugreifen, der &lt;strong>nicht&lt;/strong> innerhalb von Jython ausgeführt wird.
Dafür benötigen wir einen Blick in das Python Projekt Setup.&lt;/p>
&lt;div class="mermaid">---
title: Python Setup
config:
look: handDrawn
theme: neutral
---
flowchart LR
subgraph web[fas:fa-globe Web]
subgraph python[fab:fa-python Python]
python_3_12[fab:fa-python 3.12]
python_3_13[fab:fa-python 3.13]
end
subgraph packages[fas:fa-folder-tree Packages]
typer_0_15[Typer 0.15]
fastapi_0_115[FastAPI 0.115]
spacy_3_8[spaCy 3.8]
my_project_0_1[My Project 0.1]
end
end
subgraph laptop[fas:fa-laptop Laptop]
subgraph local_python[fab:fa-python Python]
local_python_3_12[fab:fa-python 3.12]
local_python_3_13[fab:fa-python 3.13]
end
subgraph local_packages[fas:fa-folder-tree Packages]
local_typer_0_15[Typer 0.15]
local_fastapi_0_115[FastAPI 0.115]
subgraph local_spacy_3_8[spaCy 3.8]
c_code[fab:fa-c Code]
compiled_c_code[fab:fa-c compiled]
end
end
subgraph my_project[My Project]
subgraph venv[fas:fa-folder-open venv]
venv_python_3_12[fab:fa-python 3.12]
venv_typer_0_15[Typer 0.15]
venv_fastapi_0_115[FastAPI 0.115]
venv_spacy_3_8[spaCy 3.8]
end
package_my_project[My Project]
end
end
python --(1)--> local_python
python_3_12 ~~~ local_python_3_12
python_3_13 ~~~ local_python_3_13
packages --(2)--> local_packages
typer_0_15 ~~~ local_typer_0_15
fastapi_0_115 ~~~ local_fastapi_0_115
spacy_3_8 ~~~ local_spacy_3_8
c_code --(3)--> compiled_c_code
local_python_3_12 --(4)--> venv_python_3_12
local_typer_0_15 --(4)--> venv_typer_0_15
local_fastapi_0_115 --(4)--> venv_fastapi_0_115
local_spacy_3_8 --(4)--> venv_spacy_3_8
my_project_0_1 ~~~ package_my_project
package_my_project --(5)--> my_project_0_1
&lt;/div>
&lt;p>Für ein typisches Python Projekt benötigt man fünf Schritte, die durch verschiedene Tools in unterschiedlichem Ausmaß unterstützt werden.&lt;/p>
&lt;h4 id="schritt-1-python-interpreter">Schritt 1: Python Interpreter&lt;/h4>
&lt;p>Zuerst benötigt man einen Python Interpreter, der es ermöglicht Python Code auf dem eigenen Rechner auszuführen.
Zur Verwaltung verschiedener Python Versionen auf dem Rechner gibt es zum Beispiel das Projekt &lt;a href="https://github.com/pyenv/pyenv" target="_blank" rel="noopener">pyenv&lt;/a>.&lt;/p>
&lt;h4 id="schritt-2-dependency-management">Schritt 2: Dependency Management&lt;/h4>
&lt;p>Üblicherweise werden verschiedene externe Bibliotheken benötigt.
Diese stehen zum Beispiel im &lt;a href="https://pypi.org/" target="_blank" rel="noopener">Python Package Index (PyPI)&lt;/a> zur Verfügung und können mit &lt;a href="https://pip.pypa.io/" target="_blank" rel="noopener">pip&lt;/a> verwaltet werden.&lt;/p>
&lt;p>Alternativen zur Verwaltung der Abhängigkeiten sind &lt;a href="https://python-poetry.org/" target="_blank" rel="noopener">Poetry&lt;/a>, &lt;a href="https://pip-tools.readthedocs.io/" target="_blank" rel="noopener">pip-tools&lt;/a> und &lt;a href="https://pipx.pypa.io/" target="_blank" rel="noopener">pipx&lt;/a>.&lt;/p>
&lt;h4 id="schritt-3-compiler">Schritt 3: Compiler&lt;/h4>
&lt;p>Wie schon angesprochen beinhalten manche Python Projekte nicht nur Python Code, sondern auch Code in kompilierten Sprachen.
Wenn für die von euch verwendete Kombination aus CPU und Betriebssystem (noch) kein kompiliertes Binärpaket für die Bibliothek zur Verfügung steht, dann muss das Paket ggf. auf eurem Rechner kompiliert werden.
Dafür werden entsprechende Compiler und Entwicklungspakete auf dem Rechner benötigt.&lt;/p>
&lt;p>Alternativ gibt es auf &lt;a href="https://conda-forge.org/" target="_blank" rel="noopener">conda-forge&lt;/a> eine Sammlung schon kompilierter Pakete.&lt;/p>
&lt;h4 id="schritt-4-virtuelle-umgebung">Schritt 4: Virtuelle Umgebung&lt;/h4>
&lt;p>Erfahrungsgemäß bleibt es nicht bei einem Python Projekt auf dem eigenen Rechner.
Um Konflikte zwischen den Python Versionen und/oder Abhängigkeiten zu vermeiden, ist es üblich für jedes Projekt eine eigene virtuelle Umgebung anzulegen.&lt;/p>
&lt;p>Dafür gibt es das Werkzeug &lt;a href="https://docs.python.org/3/library/venv.html" target="_blank" rel="noopener">venv&lt;/a>, welches früher ein separates Paket war, und seit Python 3.3 in den Standard übernommen wurde.&lt;/p>
&lt;h4 id="schritt-5-package-und-release-management">Schritt 5: Package und Release Management&lt;/h4>
&lt;p>Möchte man das Projekt anschließend für andere z.B. im &lt;em>Python Package Index&lt;/em> zur Verfügung stellen, dann muss es davor noch in das passende Paketformat umgewandelt werden.
Da das für die Benutzung mit OpenRefine nicht relevant ist, wird dieser Schritt hier nicht vertieft.&lt;/p>
&lt;h2 id="uv">uv&lt;/h2>
&lt;p>Das oben beschriebene Setup klingt recht kompliziert und daher abschreckend gerade für kleinere Experimente.
Spätestens seit 2025 setzt sich bei Python Entwicklern hier das Projekt &lt;a href="https://docs.astral.sh/uv/" target="_blank" rel="noopener">uv&lt;/a> durch, welches die Schritte 1, 2, 4 und 5 in einem Werkzeug vereint und das Python Setup dadurch deutlich vereinfacht.&lt;/p>
&lt;p>Für die &lt;a href="https://docs.astral.sh/uv/getting-started/installation/" target="_blank" rel="noopener">Installation von uv&lt;/a> werden mehrere einfache und direkte Wege beschrieben.&lt;/p>
&lt;div class="alert alert-info">
&lt;div>
Sollte man mit dem &lt;em>Windows-Subsystem for Linux&lt;/em> (WSL) arbeiten, dann benötigt man die Installationsanleitung für Linux, auch wenn man Windows als Betriebssystem hat.
&lt;/div>
&lt;/div>
&lt;p>&lt;strong>uv&lt;/strong> hat (quasi) drei für uns relevante Modi:&lt;/p>
&lt;ul>
&lt;li>&lt;strong>uvx&lt;/strong> zum Ausführen von Tools.&lt;/li>
&lt;li>&lt;strong>uv run&lt;/strong> zum Ausführen von Skripten.&lt;/li>
&lt;li>&lt;strong>uv&lt;/strong> zum Arbeiten mit Projekten&lt;br>
(mehrere abhängige Python Dateien, separates Dependency Management).&lt;/li>
&lt;/ul>
&lt;p>Wir konzentrieren uns in dieser Anleitung auf die ersten beiden.&lt;/p>
&lt;h2 id="reconciliation-service">Reconciliation Service&lt;/h2>
&lt;p>Um die Verwendung von &lt;em>uvx&lt;/em> zum Ausführen von externen Python Werkzeugen zu demonstrieren, erstellen wir einen eigenen &lt;em>Reconciliation Service&lt;/em> basierend auf einer CSV-Datei mit &lt;em>uvx&lt;/em> und &lt;a href="https://github.com/gitonthescene/csv-reconcile" target="_blank" rel="noopener">csv-reconcile&lt;/a>.
Zum Herunterladen der CSV-Datei von &lt;a href="https://fdmlab.landesarchiv-bw.de/workshop/openrefine-fortgeschrittene/12-daten-zwischen-projekten-abgleichen/">12 Daten zwischen Projekten abgleichen&lt;/a> verwenden wir &lt;em>uvx&lt;/em> mit &lt;a href="https://httpie.io/" target="_blank" rel="noopener">httpie&lt;/a>.&lt;/p>
&lt;p>In einem Terminal wie iTerm, xTerm, Bash oder Powershell führen wir den folgenden Befehl aus.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">uvx --from httpie http --download GET https://fdmlab.landesarchiv-bw.de/data/openrefine-workshop/12_staedte-in-bw-geokoordinaten.csv
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Dieses kompakte Snippet lädt die zu diesem Zeitpunkt standardmäßige Python Version und die aktuellste Version von &lt;em>httpie&lt;/em> herunter, erstellt damit eine virtuelle Umgebung (&lt;em>venv&lt;/em>) und führt darin den Befehl &lt;code>http --download GET ...&lt;/code> aus.&lt;/p>
&lt;p>Den &lt;em>Reconciliation Service&lt;/em> basierend auf der im letzten Schritt heruntergeladenen Datei erstellen wir in zwei Schritten:&lt;/p>
&lt;ol>
&lt;li>Datenbank für &lt;em>Reconcilation Service&lt;/em> erstellen&lt;/li>
&lt;li>&lt;em>Reconciliation Service&lt;/em> starten&lt;/li>
&lt;/ol>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">uvx csv-reconcile init 12_staedte-in-bw-geokoordinaten.csv &lt;span class="s2">&amp;#34;GND ID&amp;#34;&lt;/span> &lt;span class="s2">&amp;#34;Name&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Mit diesem Snippet erstellen wir die Datenbank für den &lt;em>Reconciliation Service&lt;/em> und legen die Spalte &amp;ldquo;GND ID&amp;rdquo; als ID-Spalte fest und die Spalte &amp;ldquo;Name&amp;rdquo; als Standardspalte für den Abgleich.
Den &lt;em>Reconciliation Service&lt;/em> selbst starten wir mit dem folgenden Befehl.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">uvx csv-reconcile serve
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>In OpenRefine können wir den &lt;em>Reconciliation Service&lt;/em> anschließend hinzufügen mit: &lt;code>http://127.0.0.1:5000/reconcile&lt;/code>.&lt;/p>
&lt;h3 id="datenbank-mit-eigener-konfiguration">Datenbank mit eigener Konfiguration&lt;/h3>
&lt;p>Der oben erstelle &lt;em>Reconciliation Service&lt;/em> ist recht generisch und es fehlt z.B. noch die Vorschaufunktion für die einzelnen Elemente.
Um den Service nach unseren Anforderungen zu konfigurieren, erstellen wir eine Datei &lt;code>config.py&lt;/code> mit dem folgenden Inhalt.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="n">SERVER_NAME&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;localhost:5000&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">CSVKWARGS&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="p">{&lt;/span>&lt;span class="s1">&amp;#39;delimiter&amp;#39;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s1">&amp;#39;,&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s1">&amp;#39;quotechar&amp;#39;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s1">&amp;#39;&amp;#34;&amp;#39;&lt;/span>&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">CSVENCODING&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s1">&amp;#39;UTF-8&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">MANIFEST&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;name&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;Städte in BW Reconciliation Service&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;identifierSpace&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;https://normdaten.landesarchiv-bw.de/ids&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;schemaSpace&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;https://normdaten.landesarchiv-bw.de/schema&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;extend&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;propose_properties&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;service_url&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;http://localhost:5000&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;service_path&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;/properties&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;preview&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;url&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;http://localhost:5000/preview/{{id}}&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;width&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="mi">500&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;height&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="mi">300&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Anschließend erstellen wir die &lt;em>Reconciliation&lt;/em> Datenbank mit der neuen Konfiguration.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">uvx csv-reconcile init --config config.py 12_staedte-in-bw-geokoordinaten.csv &lt;span class="s2">&amp;#34;GND ID&amp;#34;&lt;/span> &lt;span class="s2">&amp;#34;Name&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Der neue Service ist nach dem Starten unter &lt;code>http://localhost:5000/reconcile&lt;/code> erreichbar.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">uvx csv-reconcile serve
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;div class="alert alert-info">
&lt;div>
In OpenRefine müssen wir den CSV &lt;em>Reconciliation Service&lt;/em> aktuell bei jeder Änderung der &lt;strong>Konfiguration&lt;/strong> neu hinzufügen.
&lt;/div>
&lt;/div>
&lt;p>Der &lt;em>Reconciliation Service&lt;/em> kann jetzt wie in Abbildung 2 mit dem Beispiel aus &lt;a href="https://fdmlab.landesarchiv-bw.de/workshop/openrefine-fortgeschrittene/12-daten-zwischen-projekten-abgleichen/">12 Daten zwischen Projekten abgleichen&lt;/a> getestet werden.&lt;/p>
&lt;figure id="figure-screencast-zum-reconciling-mit-openrefine-und-csv-datei">
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="Screencast zum *Reconciling* mit OpenRefine und CSV-Datei."
src="https://fdmlab.landesarchiv-bw.de/workshop/openrefine-fortgeschrittene/20-python-mit-openrefine/screencast-openrefine-csv-reconciling.gif"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;figcaption data-pre="Abbildung&amp;nbsp;" data-post=":&amp;nbsp;" class="numbered">
Screencast zum &lt;em>Reconciling&lt;/em> mit OpenRefine und CSV-Datei.
&lt;/figcaption>&lt;/figure>
&lt;h2 id="eigene-skripte">Eigene Skripte&lt;/h2>
&lt;p>Um &lt;em>Command Line Interfaces&lt;/em> (CLIs) zu erstellen, gibt es in Python die Standardbibliothek &lt;a href="https://docs.python.org/3/library/argparse.html" target="_blank" rel="noopener">argparse&lt;/a>.
Meistens möchte man aber &amp;ldquo;nur mal schnell&amp;rdquo; aus einer Python Funktion ein Werkzeug erstellen, welches von der Kommandozeile aufgerufen werden kann.
Ein nützliches Python Projekt dafür ist &lt;a href="https://typer.tiangolo.com/" target="_blank" rel="noopener">typer&lt;/a>.&lt;/p>
&lt;h3 id="typer-hello-world-beispiel">Typer Hello World Beispiel&lt;/h3>
&lt;p>Ein einfaches &amp;ldquo;Hello World&amp;rdquo; Beispiel mit &lt;em>uv&lt;/em> und &lt;em>Typer&lt;/em> ist im folgenden Quellcode aus &lt;code>hello_world.py&lt;/code> abgebildet.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># /// script&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># requires-python = &amp;#34;&amp;gt;=3.12&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># dependencies = [&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># &amp;#34;typer&amp;#34;,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># ]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># ///&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">import&lt;/span> &lt;span class="nn">typer&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">def&lt;/span> &lt;span class="nf">hello_world&lt;/span>&lt;span class="p">():&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;Hello World&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">if&lt;/span> &lt;span class="vm">__name__&lt;/span> &lt;span class="o">==&lt;/span> &lt;span class="s2">&amp;#34;__main__&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">typer&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">run&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">hello_world&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Zu Beginn wird über &lt;a href="https://packaging.python.org/en/latest/specifications/inline-script-metadata/#script-type" target="_blank" rel="noopener">Inline Metadaten&lt;/a> definiert, dass das Skript mit Python 3.12 oder neuer ausgeführt werden soll und das Skript zusätzlich die externe Abhängigkeit &lt;a href="https://typer.tiangolo.com/" target="_blank" rel="noopener">typer&lt;/a> benötigt.&lt;/p>
&lt;p>Das Werkzeug &lt;em>uv&lt;/em> unterstützt diese inline Metadaten, so dass zum Ausführen dieses Skriptes in einem Terminal lediglich &lt;code>uv run hello_world.py&lt;/code> ausgeführt werden muss.&lt;/p>
&lt;p>Das Werkzeug &lt;em>Typer&lt;/em> übersetzt den CLI-Aufruf für die Python Funktion, und validiert und konvertiert dabei die Eingabedaten.&lt;/p>
&lt;h3 id="typer-beispiel-mit-parametern">Typer Beispiel mit Parametern&lt;/h3>
&lt;p>Wir beginnen mit einem einfachen Beispiel.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># /// script&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># requires-python = &amp;#34;&amp;gt;=3.12&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># dependencies = [&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># &amp;#34;typer&amp;#34;,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># ]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># ///&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">import&lt;/span> &lt;span class="nn">typer&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">def&lt;/span> &lt;span class="nf">add&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">a&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">b&lt;/span>&lt;span class="p">):&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">a&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="n">b&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">if&lt;/span> &lt;span class="vm">__name__&lt;/span> &lt;span class="o">==&lt;/span> &lt;span class="s2">&amp;#34;__main__&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">typer&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">run&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">add&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Die Funktion &lt;code>add&lt;/code> soll zwei Parameter &lt;code>a&lt;/code> und &lt;code>b&lt;/code> miteinander addieren und dann ausgeben.
Zum Ausgeben des Ergebnisses verwenden wir die Funktion &lt;code>print&lt;/code>.
Das Werkzeug &lt;code>typer&lt;/code> erkennt automatisch die beiden Parameter &lt;code>a&lt;/code> und &lt;code>b&lt;/code> und meldet, wenn diese nicht gesetzt sind.
Unter &lt;code>uv run add.py --help&lt;/code> erhalten wir einen Informationstext zur Benutzung unseres CLI-Tools.&lt;/p>
&lt;p>Standardmäßig werden die Parameter als Text interpretiert.
Mit so genannten &lt;a href="https://docs.python.org/3/library/typing.html" target="_blank" rel="noopener">Type Hints&lt;/a> können wir &lt;em>Typer&lt;/em> mitteilen, dass wir hier Zahlen erwarten.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="k">def&lt;/span> &lt;span class="nf">add&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">a&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="nb">int&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">b&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="nb">int&lt;/span>&lt;span class="p">):&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">a&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="n">b&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Es ist auch möglich, optionale Parameter wie &lt;code>c&lt;/code> mit anzugeben.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="k">def&lt;/span> &lt;span class="nf">add&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">a&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="nb">int&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">b&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="nb">int&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">c&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="nb">int&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">):&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">a&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="n">b&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="n">c&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Individuelle Konfigurationen können mit &lt;a href="https://docs.python.org/3/library/typing.html#typing.Annotated" target="_blank" rel="noopener">Type Annotations&lt;/a> hinterlegt werden.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="k">def&lt;/span> &lt;span class="nf">add&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">a&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">b&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">c&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="n">Annotated&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="nb">int&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">typer&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">Argument&lt;/span>&lt;span class="p">()]&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">):&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">a&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="n">b&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="n">c&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Mit den Annotationen lässt sich bei Bedarf der Text für die Hilfe weiter spezifizieren.
Hier das fertige Skript mit ausführlicherem Hilfstext.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># /// script&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># requires-python = &amp;#34;&amp;gt;=3.12&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># dependencies = [&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># &amp;#34;typer&amp;#34;,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># ]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># ///&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">import&lt;/span> &lt;span class="nn">typer&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">from&lt;/span> &lt;span class="nn">typing_extensions&lt;/span> &lt;span class="kn">import&lt;/span> &lt;span class="n">Annotated&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">def&lt;/span> &lt;span class="nf">add&lt;/span>&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">a&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="n">Annotated&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="nb">int&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">typer&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">Argument&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">help&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;The first number to add.&amp;#34;&lt;/span>&lt;span class="p">)],&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">b&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="n">Annotated&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="nb">int&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">typer&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">Argument&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">help&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;The second number to add.&amp;#34;&lt;/span>&lt;span class="p">)],&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">c&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="n">Annotated&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="nb">int&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">typer&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">Argument&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">help&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;The optionally third number to add.&amp;#34;&lt;/span>&lt;span class="p">)]&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">):&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;&amp;#34;&amp;#34;
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2"> Add the numbers in `a` and `b` and optionally `c` if `c` is provided.
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2"> &amp;#34;&amp;#34;&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">a&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="n">b&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="n">c&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">if&lt;/span> &lt;span class="vm">__name__&lt;/span> &lt;span class="o">==&lt;/span> &lt;span class="s2">&amp;#34;__main__&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">typer&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">run&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">add&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Das Praktische an &lt;em>Typer&lt;/em> ist, dass man &amp;ldquo;nur zum Ausprobieren&amp;rdquo; lediglich die &lt;em>type hints&lt;/em> und den Aufruf von &lt;em>Typer&lt;/em> im Skript ergänzen muss.
Bei Bedarf können ausführlichere Hilfstexte oder Validierungen hinterlegt werden, deren Ergebnis in Abbildung 3 gezeigt ist.&lt;/p>
&lt;figure id="figure-screenshot-terminal-mit-von-typer-generierten-hilfstext">
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="Screenshot Terminal mit von *Typer* generierten Hilfstext." srcset="
/workshop/openrefine-fortgeschrittene/20-python-mit-openrefine/screenshot-terminal-typer_hu0d8bcb7ebbd1732e66a8e438ddf2504c_22144_b0035b32e843cd9c416ec72c36cdae2a.webp 400w,
/workshop/openrefine-fortgeschrittene/20-python-mit-openrefine/screenshot-terminal-typer_hu0d8bcb7ebbd1732e66a8e438ddf2504c_22144_02ae2c3f464e13330fa05f52c91a98b6.webp 760w,
/workshop/openrefine-fortgeschrittene/20-python-mit-openrefine/screenshot-terminal-typer_hu0d8bcb7ebbd1732e66a8e438ddf2504c_22144_1200x1200_fit_q75_h2_lanczos_3.webp 1200w"
src="https://fdmlab.landesarchiv-bw.de/workshop/openrefine-fortgeschrittene/20-python-mit-openrefine/screenshot-terminal-typer_hu0d8bcb7ebbd1732e66a8e438ddf2504c_22144_b0035b32e843cd9c416ec72c36cdae2a.webp"
width="542"
height="231"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;figcaption data-pre="Abbildung&amp;nbsp;" data-post=":&amp;nbsp;" class="numbered">
Screenshot Terminal mit von &lt;em>Typer&lt;/em> generierten Hilfstext.
&lt;/figcaption>&lt;/figure>
&lt;h3 id="zugriff-von-openrefine-auf-python-skript">Zugriff von OpenRefine auf Python Skript&lt;/h3>
&lt;p>Von OpenRefine heraus, lässt sich mit Jython recht unkompliziert auf das externe Python Skripte zugreifen.
Es muss lediglich der Pfad des Skriptes in dem Jython Snippet unten angepasst werden.
Ggf. müssen auch noch Parameter für das Skript ergänzt werden.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="kn">import&lt;/span> &lt;span class="nn">subprocess&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">script&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s2">&amp;#34;C:&lt;/span>&lt;span class="se">\\&lt;/span>&lt;span class="s2">...&lt;/span>&lt;span class="se">\\&lt;/span>&lt;span class="s2">python_script.py&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">res&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">subprocess&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">check_output&lt;/span>&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">[&lt;/span>&lt;span class="s2">&amp;#34;uv&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;run&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">script&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="se">\&amp;#34;&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="o">+&lt;/span>&lt;span class="n">value&lt;/span>&lt;span class="o">+&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="se">\&amp;#34;&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="p">],&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">shell&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="kc">True&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">return&lt;/span> &lt;span class="n">res&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="probleme-beim-zugriff-von-openrefine-auf-python-skripte">Probleme beim Zugriff von OpenRefine auf Python Skripte&lt;/h3>
&lt;p>Der direkte Zugriff auf ein Skript ist erst einmal relativ performant, hat in der Praxis aber mehrere Probleme.&lt;/p>
&lt;ol>
&lt;li>Die korrekte Übergabe von Daten an das Skript via Parametern ist nicht ganz so einfach. Besonders, wenn die Daten größer sind ggf. Sonderzeichen enthalten, &amp;hellip;&lt;/li>
&lt;li>Man ist selbst für die Fehlerbehandlung verantwortlich. Also dass die Skripte auch irgendwann beendet werden, bei zu langer Laufzeit abgebrochen werden, usw.&lt;/li>
&lt;li>Es wird lediglich Text zurückgegeben. Die Interpretation in ein bestimmtes Format muss dann in Jython oder in einem Nachbearbeitungsschritt erfolgen.&lt;/li>
&lt;li>Manche Skripte oder Tools müssen initial erst einmal Daten in den Arbeitsspeicher laden. Insbesondere bei Machine Learning Anwendungen kann das mehrere Sekunden dauern. Dies erfolgt bei jedem Skriptaufruf wieder erneut.&lt;/li>
&lt;/ol>
&lt;p>Daher ist es wesentlich stabiler stattdessen mit eigenen Web-APIs zu arbeiten.&lt;/p>
&lt;h2 id="eigene-web-apis-mit-fastapi">Eigene Web-APIs mit FastAPI&lt;/h2>
&lt;div class="mermaid">---
title: Script vs Web-API
config:
look: handDrawn
theme: neutral
---
flowchart LR
subgraph openrefine["OpenRefine"]
subgraph jython["Jython"]
jython_code["Jython Code"]
end
end
subgraph venv
script["fab:fa-python Skript"]
end
subgraph uvicorn["Uvicorn"]
subgraph fastapi["FastAPI"]
python_code["fab:fa-python Code"]
end
end
jython_code -.-> script
jython_code -.-> script
jython_code -.-> script
jython_code -.-> script
jython_code -.-> script
jython_code -.-> script
jython_code -.-> script
jython_code -.-> script
jython_code -.-> script
jython_code &lt;--HTTP--> python_code
&lt;/div>
&lt;p>Für Web-APIs gibt es etablierte und stabile Protokolle zum Austausch von Daten.
Ähnlich wie mit &lt;em>Typer&lt;/em> können wir mit &lt;a href="https://fastapi.tiangolo.com/" target="_blank" rel="noopener">FastAPI&lt;/a> unsere Python-Funktionen als Web-API zur Verfügung stellen.
Mit einem Server wie &lt;a href="https://www.uvicorn.org/" target="_blank" rel="noopener">uvicorn&lt;/a> sorgen wir dabei für eine Stabilität der angestoßenen Prozesse für die Abfragen.&lt;/p>
&lt;h3 id="beispielcode-für-spacy">Beispielcode für spaCy&lt;/h3>
&lt;p>Das folgende Skript lädt ein deutschsprachiges Modell von &lt;a href="https://spacy.io" target="_blank" rel="noopener">spaCy&lt;/a> und berechnet über &lt;a href="https://de.wikipedia.org/wiki/Worteinbettung" target="_blank" rel="noopener">Word Embeddings&lt;/a> die Ähnlichkeit bzw. hier die Distanz der beiden übergebenen Texte.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># /// script&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># requires-python = &amp;#34;&amp;gt;=3.12,&amp;lt;3.13&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># dependencies = [&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># &amp;#34;spacy&amp;#34;,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># &amp;#34;typer&amp;#34;,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># &amp;#34;de_core_news_lg @ https://github.com/explosion/spacy-models/releases/download/de_core_news_lg-3.8.0/de_core_news_lg-3.8.0.tar.gz&amp;#34;,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># ]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># ///&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">import&lt;/span> &lt;span class="nn">typer&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">import&lt;/span> &lt;span class="nn">de_core_news_lg&lt;/span> &lt;span class="k">as&lt;/span> &lt;span class="nn">model&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">def&lt;/span> &lt;span class="nf">spacy_distance&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">a&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="nb">str&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">b&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="nb">str&lt;/span>&lt;span class="p">):&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">nlp&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">model&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">load&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">doc_a&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">nlp&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">a&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">doc_b&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">nlp&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">b&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">dist&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">1&lt;/span> &lt;span class="o">-&lt;/span> &lt;span class="n">doc_a&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">similarity&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">doc_b&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">dist&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">if&lt;/span> &lt;span class="vm">__name__&lt;/span> &lt;span class="o">==&lt;/span> &lt;span class="s2">&amp;#34;__main__&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">typer&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">run&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">spacy_distance&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Das Skript hat den eindeutigen Nachteil, dass es bei jedem Aufruf das &amp;ldquo;große&amp;rdquo; Sprachmodell laden muss, was mehrere Sekunden dauert.
Hier im Vergleich das Skript &lt;code>spacy_distance_fastapi.py&lt;/code>, welches die Funktionalität via &lt;a href="https://fastapi.tiangolo.com/" target="_blank" rel="noopener">FastAPI&lt;/a> zur Verfügung stellt.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># /// script&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># requires-python = &amp;#34;&amp;gt;=3.12,&amp;lt;3.13&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># dependencies = [&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># &amp;#34;spacy&amp;#34;,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># &amp;#34;fastapi&amp;#34;,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># &amp;#34;uvicorn&amp;#34;,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># &amp;#34;de_core_news_lg @ https://github.com/explosion/spacy-models/releases/download/de_core_news_lg-3.8.0/de_core_news_lg-3.8.0.tar.gz&amp;#34;,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># ]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># ///&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">import&lt;/span> &lt;span class="nn">de_core_news_lg&lt;/span> &lt;span class="k">as&lt;/span> &lt;span class="nn">model&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">import&lt;/span> &lt;span class="nn">uvicorn&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">from&lt;/span> &lt;span class="nn">fastapi&lt;/span> &lt;span class="kn">import&lt;/span> &lt;span class="n">FastAPI&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">app&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">FastAPI&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">nlp&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">model&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">load&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nd">@app.get&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;/distance&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">def&lt;/span> &lt;span class="nf">spacy_distance&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">a&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="nb">str&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">b&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="nb">str&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">-&amp;gt;&lt;/span> &lt;span class="nb">float&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">doc_a&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">nlp&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">a&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">doc_b&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">nlp&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">b&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">dist&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">1&lt;/span> &lt;span class="o">-&lt;/span> &lt;span class="n">doc_a&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">similarity&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">doc_b&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="n">dist&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">if&lt;/span> &lt;span class="vm">__name__&lt;/span> &lt;span class="o">==&lt;/span> &lt;span class="s2">&amp;#34;__main__&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">uvicorn&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">run&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;spacy_distance_fastapi:app&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">host&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;127.0.0.1&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">port&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="mi">5000&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Die Verarbeitungspipeline für die Texte mit dem &amp;ldquo;großen&amp;rdquo; Sprachmodell wird außerhalb der Python Methode definiert, weshalb das Modell pro Aufruf nur einmal aufgerufen werden muss.
Im Vergleich zum direkten Skriptaufruf, ist der Zugriff auf unsere lokale Web-API zwar etwas langsamer.
Wir profitieren aber von der Müglichkeit ladeintensive Prozesse nur einmal beim Starten auszuführen, sowie von dem zusätzlichen Protokoll im Bereich Fehlerbehandlung, Validierung von Eingaben und Antworten.&lt;/p>
&lt;p>Ähnlich wie bei &lt;em>Typer&lt;/em> übernimmt &lt;em>FastAPI&lt;/em> hier das Mapping der Benutzeranfrage auf die entsprechende Python Funktion.
Gleich wie bei &lt;em>Typer&lt;/em> werden &lt;em>Type Hints&lt;/em> für das Mapping, die Dokumentation und die Validierung verwendet.
Auch bei &lt;em>FastAPI&lt;/em> kann die Dokumentation mit weiteren Annotationen erweitert und personalisiert werden.&lt;/p>
&lt;p>Somit lassen sich mit FastAPI eigene Web-APIs ähnlich leicht erstellen, wie einfache Python Skripte mit &lt;em>Typer&lt;/em>.
Ausführliche Beispiele stehen im Anhang bzw. als GitHub Gist unter &lt;a href="https://gist.github.com/b2m/cadf88263f7978be96c164a89968c44c" target="_blank" rel="noopener">spacy_fastapi.py&lt;/a> und &lt;a href="https://gist.github.com/b2m/91f3b812bcf0975c4d2cb3230099366a" target="_blank" rel="noopener">rapidfuzz_fastapi.py&lt;/a> zur Verfügung.&lt;/p>
&lt;p>Von OpenRefine heraus kann man via Jython auf die (lokalen) Web-APIs zugreifen.&lt;/p>
&lt;h3 id="zugriff-via-get">Zugriff via GET&lt;/h3>
&lt;p>Web-APIs unterscheiden für den Abruf von Daten zwischen &lt;em>GET-&lt;/em> und &lt;em>POST-Requests&lt;/em> (Anfragen).
Für &lt;em>GET-Requests&lt;/em> gibt es in OpenRefine die Möglichkeit den Dialog &lt;a href="https://openrefine.org/docs/manual/columnediting#add-column-by-fetching-urls" target="_blank" rel="noopener">Add column by fetching URLs&lt;/a> zum Nachladen von Daten zu verwenden.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="s2">&amp;#34;http://localhost:5000/ner?text=&amp;#34;&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="nx">escape&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">value&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;url&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Hier kann man mit einfachem GREL die benötigte URL zusammen bauen.
Man sollte jedoch daran denken, die Parameter mit &lt;a href="https://openrefine.org/docs/manual/grelfunctions#escapes-s-mode" target="_blank" rel="noopener">escape&lt;/a> für die URL kompatibel aufzubereiten.&lt;/p>
&lt;p>In Abbildung 4 ist der Dialog aus &lt;a href="https://fdmlab.landesarchiv-bw.de/workshop/openrefine-fortgeschrittene/18-nachladen-von-geokoordinaten/">18 Nachladen von Geokoordinaten&lt;/a> gezeigt.&lt;/p>
&lt;figure id="figure-bildschirmfoto-des-dialogs-zum-nachladen-von-urls-für-geonames">
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img src="../18-nachladen-von-geokoordinaten/screenshot-openrefine-add-by-url.png" alt="Bildschirmfoto des Dialogs zum Nachladen von URLs für GeoNames." loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;figcaption data-pre="Abbildung&amp;nbsp;" data-post=":&amp;nbsp;" class="numbered">
Bildschirmfoto des Dialogs zum Nachladen von URLs für GeoNames.
&lt;/figcaption>&lt;/figure>
&lt;p>Möchte man eine Web-API z.B. von einem &lt;em>Facet&lt;/em> oder einem Clustering-Dialog heraus aufrufen, benötigt man dafür das folgende Jython-Snippet um einen validen &lt;em>GET-Request&lt;/em> zu erstellen.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="kn">import&lt;/span> &lt;span class="nn">json&lt;/span>&lt;span class="o">,&lt;/span> &lt;span class="nn">urllib&lt;/span>&lt;span class="o">,&lt;/span> &lt;span class="nn">urllib2&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">url&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s2">&amp;#34;http://localhost:5000/ner&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">request_data&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">urllib&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">urlencode&lt;/span>&lt;span class="p">({&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;text&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="n">value&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">encode&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;utf-8&amp;#34;&lt;/span>&lt;span class="p">),&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">})&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">response&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">urllib2&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">urlopen&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">url&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="s2">&amp;#34;?&amp;#34;&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="n">request_data&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">return&lt;/span> &lt;span class="n">json&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">dumps&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">json&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">load&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">response&lt;/span>&lt;span class="p">),&lt;/span> &lt;span class="n">ensure_ascii&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="kc">False&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;div class="alert alert-note">
&lt;div>
&lt;strong>Zur Erinnerung:&lt;/strong> Es gibt Python Bibliotheken wie &lt;a href="https://requests.readthedocs.io/" target="_blank" rel="noopener">requests&lt;/a>, die das Erstellen und Verarbeiten von Web-Requests deutlich vereinfachen. Wir arbeiten in OpenRefine aber mit Jython und können daher nicht einfach auf externe Bibliotheken zugreifen.
&lt;/div>
&lt;/div>
&lt;h3 id="zugriff-via-get-und-form">Zugriff via GET und Form&lt;/h3>
&lt;p>Manche Web-APIs erwarten einen &lt;em>GET-Request&lt;/em> mit zusätzlichem Nutzdaten z.B. aus einem Formular.
Das lässt sich in Jython / Python 2.7 mit folgendem Snippet umsetzen.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="kn">import&lt;/span> &lt;span class="nn">json&lt;/span>&lt;span class="o">,&lt;/span> &lt;span class="nn">urllib&lt;/span>&lt;span class="o">,&lt;/span> &lt;span class="nn">urllib2&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">url&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s2">&amp;#34;http://localhost:5000/ner&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">request_data&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">urllib&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">urlencode&lt;/span>&lt;span class="p">({&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;text&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="n">value&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">encode&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;utf-8&amp;#34;&lt;/span>&lt;span class="p">),&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">})&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">response&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">urllib2&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">urlopen&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">url&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">request_data&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">return&lt;/span> &lt;span class="n">json&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">dumps&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">json&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">load&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">response&lt;/span>&lt;span class="p">),&lt;/span> &lt;span class="n">ensure_ascii&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="kc">False&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Der Unterschied zum letzten Beispiel ist, dass &lt;code>request_data&lt;/code> als zusätzliche Nutzdaten mit einem Komma getrennt an &lt;code>urllib2&lt;/code> übergeben werden, anstatt sie mit an die URL zu kodieren.&lt;/p>
&lt;h3 id="zugriff-via-post">Zugriff via POST&lt;/h3>
&lt;p>Der in den Beispielen im Anhang verwende &lt;em>Use-Case&lt;/em> ist das Verwenden von &lt;em>POST-Requests&lt;/em>.
Hier werden die Nutzdaten als &lt;a href="https://www.json.org/" target="_blank" rel="noopener">JSON&lt;/a> kodiert an den &lt;em>Request&lt;/em> angehängt.
Das macht die Kodierung der Daten in der Anfrage komplexer, gleichzeitig aber die Übermittlung stabiler.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="kn">import&lt;/span> &lt;span class="nn">json&lt;/span>&lt;span class="o">,&lt;/span> &lt;span class="nn">urllib&lt;/span>&lt;span class="o">,&lt;/span> &lt;span class="nn">urllib2&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">url&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s2">&amp;#34;http://localhost:5000/ner&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">request_data&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">json&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">dumps&lt;/span>&lt;span class="p">({&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;text&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="n">value&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">encode&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;utf-8&amp;#34;&lt;/span>&lt;span class="p">),&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">})&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">request&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">urllib2&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">Request&lt;/span>&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">url&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">request_data&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{&lt;/span>&lt;span class="s2">&amp;#34;Content-Type&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;application/json&amp;#34;&lt;/span>&lt;span class="p">},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">response&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">urllib2&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">urlopen&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">request&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">return&lt;/span> &lt;span class="n">json&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">dumps&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">json&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">load&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">response&lt;/span>&lt;span class="p">),&lt;/span> &lt;span class="n">ensure_ascii&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="kc">False&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Der komplette Workflow vom Starten des Web-Service, bis zur Verwendung von &lt;a href="https://rapidfuzz.github.io/RapidFuzz/" target="_blank" rel="noopener">RapidFuzz&lt;/a> als eigene Clustering Methode in OpenRefine ist in dem Screencast in Abbildung 5 gezeigt.&lt;/p>
&lt;figure id="figure-screencast-zur-verwendung-von-uv-fastapi-und-rapidfuzz-als-eigene-clustering-methode-bei-openrefine">
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="Screencast zur Verwendung von uv, FastAPI und RapidFuzz als eigene Clustering Methode bei OpenRefine."
src="https://fdmlab.landesarchiv-bw.de/workshop/openrefine-fortgeschrittene/20-python-mit-openrefine/screencast-openrefine-custom-clustering-distance-rapidfuzz.gif"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;figcaption data-pre="Abbildung&amp;nbsp;" data-post=":&amp;nbsp;" class="numbered">
Screencast zur Verwendung von uv, FastAPI und RapidFuzz als eigene Clustering Methode bei OpenRefine.
&lt;/figcaption>&lt;/figure>
&lt;h2 id="fazit">Fazit&lt;/h2>
&lt;p>Kleinere Skripte mit Jython / Python 2.7 in OpenRefine sind möglich, jedoch gerade beim Clustering oder bei der Nachnutzung von externen Python Projekten problematisch.&lt;/p>
&lt;p>Mit &lt;a href="https://typer.tiangolo.com/" target="_blank" rel="noopener">Typer&lt;/a> und &lt;a href="ttps://fastapi.tiangolo.com/">FastAPI&lt;/a> lassen sich aus Python Funktionen heraus schnell CLI-Tools oder Web-APIs erstellen.
Die beiden Werkzeuge ermöglichen es sowohl mit wenig Aufwand Prototypen zu erstellen, als auch diese zu dokumentierten praktischen Tools zu erweitern.&lt;/p>
&lt;p>Mit &lt;a href="https://docs.astral.sh/uv/" target="_blank" rel="noopener">uv&lt;/a> sind die Hürden für das Erstellen von indivduellen Python Umgebungen für einzelne Skripte sehr stark gesenkt worden.
Das reduziert nicht nur den Entwicklungsaufwand, sondern erleichtert auch die Nachnutzung von Skripten für Nutzerinnen und Nutzer.&lt;/p>
&lt;p>Mit der Kombination aus Jython, uv und wahlweise Typer oder FastAPI lassen sich dadurch modernste Python Anwendungen direkt mit OpenRefine verbinden.&lt;/p>
&lt;h2 id="anhang">Anhang&lt;/h2>
&lt;h3 id="fastapi-wrapper-für-spacy">FastAPI Wrapper für spaCy&lt;/h3>
&lt;script type="application/javascript" src="https://gist.github.com/b2m/cadf88263f7978be96c164a89968c44c.js?file=spacy_fastapi.py">&lt;/script>
&lt;h3 id="fastapi-wrapper-für-rapidfuzz">FastAPI Wrapper für RapidFuzz&lt;/h3>
&lt;script type="application/javascript" src="https://gist.github.com/b2m/91f3b812bcf0975c4d2cb3230099366a.js?file=rapidfuzz_fastapi.py">&lt;/script></description></item><item><title>Workshop - Daten mit OpenRefine exportieren</title><link>https://fdmlab.landesarchiv-bw.de/workshop/openrefine-einsteiger/04-exportieren/</link><pubDate>Fri, 01 Apr 2022 00:00:00 +0000</pubDate><guid>https://fdmlab.landesarchiv-bw.de/workshop/openrefine-einsteiger/04-exportieren/</guid><description>&lt;p>Wir exportieren Daten mit OpenRefine in unterschiedliche Formate.&lt;/p>
&lt;blockquote>
&lt;p>Daten exportieren in der &lt;a href="https://docs.openrefine.org/manual/exporting" target="_blank" rel="noopener">OpenRefine Dokumentation&lt;/a>.&lt;/p>
&lt;/blockquote>
&lt;div class="alert alert-note">
Dieser Workshop wurde erstellt mit OpenRefine Version 3.5.0.&lt;br>
Dieser Workshop wurde zuletzt getestet mit OpenRefine Version &lt;strong>3.9.3&lt;/strong>.
&lt;/div>
&lt;h2 id="hintergrund">Hintergrund&lt;/h2>
&lt;p>OpenRefine bietet sowohl verschiedene fertige Exportmöglichkeiten an als auch die Möglichkeit, eigene Formate (JSON, XML) zu erstellen.
Wir konzentrieren uns in diesem Workshop auf tabellenartige Formate.&lt;/p>
&lt;h2 id="aufgabe-1-daten-als-excel-exportieren">Aufgabe 1: Daten als Excel exportieren&lt;/h2>
&lt;p>Wir verwenden das Projekt &amp;ldquo;Kretschmann Kabinett III&amp;rdquo;, das wir in &lt;a href="https://fdmlab.landesarchiv-bw.de/workshop/openrefine-einsteiger/01-projekte-laden/">Projekte in OpenRefine laden und verwalten&lt;/a> erstellt haben.&lt;/p>
&lt;p>Dort erstellen wir ein &amp;ldquo;Text Facet&amp;rdquo; auf der Spalte &amp;ldquo;Geschlecht&amp;rdquo; und wählen darüber alle weiblichen Kabinettsmitglieder aus.&lt;/p>
&lt;p>Über &amp;ldquo;Export&amp;quot;
&lt;i class="far fa-caret-square-down pr-1 fa-fw">&lt;/i>&amp;quot;Excel 2007+ (.xlsx)&amp;rdquo; erzeugen wir eine Excel Datei.&lt;/p>
&lt;h2 id="aufgabe-2-daten-als-csv-exportieren">Aufgabe 2: Daten als CSV exportieren&lt;/h2>
&lt;p>Wir verwenden das gleiche Setup wie in Aufgabe 1.&lt;/p>
&lt;p>Über &amp;ldquo;Export&amp;quot;
&lt;i class="far fa-caret-square-down pr-1 fa-fw">&lt;/i>&amp;quot;Comma-separated value&amp;rdquo; erzeugen wir eine CSV Datei.&lt;/p>
&lt;h2 id="aufgabe-3-datenexport-spezifizieren">Aufgabe 3: Datenexport spezifizieren&lt;/h2>
&lt;p>Wir verwenden das gleiche Setup wie in Aufgabe 1.&lt;/p>
&lt;p>Über &amp;ldquo;Export&amp;quot;
&lt;i class="far fa-caret-square-down pr-1 fa-fw">&lt;/i>&amp;quot;Custom tabular exporter&amp;hellip;&amp;rdquo; erzeugen wir eine spezielle Datei.&lt;/p>
&lt;p>Die Einstellungen sind mit Bildschirmfotos in Abbildung 1 und 2 dokumentiert.&lt;/p>
&lt;figure id="figure-bildschirmfoto-von-openrefine-export-einstellungen-1">
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="Bildschirmfoto von OpenRefine Export Einstellungen 1." srcset="
/workshop/openrefine-einsteiger/04-exportieren/screenshot_openrefine_export_custom_1_hue6fb988869e431cf86898e9a40a00c67_32699_6be5b4fb54c9d2b5fe663ffd49b6120e.webp 400w,
/workshop/openrefine-einsteiger/04-exportieren/screenshot_openrefine_export_custom_1_hue6fb988869e431cf86898e9a40a00c67_32699_ea83a9c2c54507ac113a1cb01656c994.webp 760w,
/workshop/openrefine-einsteiger/04-exportieren/screenshot_openrefine_export_custom_1_hue6fb988869e431cf86898e9a40a00c67_32699_1200x1200_fit_q75_h2_lanczos_3.webp 1200w"
src="https://fdmlab.landesarchiv-bw.de/workshop/openrefine-einsteiger/04-exportieren/screenshot_openrefine_export_custom_1_hue6fb988869e431cf86898e9a40a00c67_32699_6be5b4fb54c9d2b5fe663ffd49b6120e.webp"
width="760"
height="557"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;figcaption data-pre="Abbildung&amp;nbsp;" data-post=":&amp;nbsp;" class="numbered">
Bildschirmfoto von OpenRefine Export Einstellungen 1.
&lt;/figcaption>&lt;/figure>
&lt;figure id="figure-bildschirmfoto-von-openrefine-export-einstellungen-2">
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="Bildschirmfoto von OpenRefine Export Einstellungen 2." srcset="
/workshop/openrefine-einsteiger/04-exportieren/screenshot_openrefine_export_custom_2_hu00bec272d2b2ffd74665ad233cc818de_17287_b6c317d217c1c0d1fa2f4ab03a46ef4b.webp 400w,
/workshop/openrefine-einsteiger/04-exportieren/screenshot_openrefine_export_custom_2_hu00bec272d2b2ffd74665ad233cc818de_17287_a9db0cab7322ff2cc4dc1513d5e62126.webp 760w,
/workshop/openrefine-einsteiger/04-exportieren/screenshot_openrefine_export_custom_2_hu00bec272d2b2ffd74665ad233cc818de_17287_1200x1200_fit_q75_h2_lanczos_3.webp 1200w"
src="https://fdmlab.landesarchiv-bw.de/workshop/openrefine-einsteiger/04-exportieren/screenshot_openrefine_export_custom_2_hu00bec272d2b2ffd74665ad233cc818de_17287_b6c317d217c1c0d1fa2f4ab03a46ef4b.webp"
width="760"
height="360"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;figcaption data-pre="Abbildung&amp;nbsp;" data-post=":&amp;nbsp;" class="numbered">
Bildschirmfoto von OpenRefine Export Einstellungen 2.
&lt;/figcaption>&lt;/figure>
&lt;p>Die Dateiendung der heruntergeladenen Datei ändern wir anschließend von &lt;code>.txt&lt;/code> nach &lt;code>.csv&lt;/code>.&lt;/p>
&lt;h2 id="aufgabe-4-datenexporte-vergleichen">Aufgabe 4: Datenexporte vergleichen&lt;/h2>
&lt;p>Wir öffnen die drei exportierten Dateien mit Excel.&lt;/p>
&lt;p>Was sind die Unterschiede zwischen den Dateien?&lt;/p>
&lt;p>Welcher Export eignet sich für welchen Anwendungsfall?&lt;/p>
&lt;details class="spoiler " id="spoiler-7">
&lt;summary>&lt;strong>Hinweise/Lösungen:&lt;/strong>&lt;/summary>
&lt;p>&lt;ul>
&lt;li>Der normale Export berücksichtigt die momentan aktiven &amp;ldquo;Facets&amp;rdquo; und Filter.&lt;/li>
&lt;li>Excel erwartet bei CSV ein Semikolon &lt;code>;&lt;/code> als Trennzeichen und &lt;code>windows-1252&lt;/code> als Kodierung. Daher sieht die erste CSV-Datei in Excel &amp;ldquo;seltsam&amp;rdquo; aus. &lt;sup id="fnref:1">&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref">1&lt;/a>&lt;/sup>&lt;/li>
&lt;li>Der normale CSV Export von OpenRefine ist mit Komma &lt;code>,&lt;/code> getrennt und verwendet &lt;code>utf-8&lt;/code> als Kodierung, wie es von den meisten Anwendungen erwartet wird.&lt;/li>
&lt;li>Beim spezifischen Datenexport hat man die Kontrolle darüber, was exportiert wird und kann Trennzeichen, Kodierungen, &amp;hellip; beeinflussen.&lt;/li>
&lt;li>Im FDMLab verwenden wir &lt;code>xlsx&lt;/code>, wenn die Daten in Excel weiter bearbeitet werden sollen, und &lt;code>csv&lt;/code>, wenn wir die Daten mit anderen Anwendungen weiter bearbeiten.&lt;/li>
&lt;/ul>
&lt;div class="footnotes" role="doc-endnotes">
&lt;hr>
&lt;ol>
&lt;li id="fn:1">
&lt;p>Microsoft Excel hat einen &lt;a href="https://support.microsoft.com/de-de/office/textimport-assistent-c5b02af6-fda1-4440-899f-f78bafe41857" target="_blank" rel="noopener">Textimport-Assistenten&lt;/a>, mit dem auch andere Formate importiert werden können.&amp;#160;&lt;a href="#fnref:1" class="footnote-backref" role="doc-backlink">&amp;#x21a9;&amp;#xfe0e;&lt;/a>&lt;/p>
&lt;/li>
&lt;/ol>
&lt;/div>
&lt;/p>
&lt;/details>
&lt;h2 id="fazit">Fazit&lt;/h2>
&lt;p>OpenRefine kann die Projekte in gängige Formate exportieren.
Das ist schnell und bequem. Komplexer wird es bei verschachtelten Formaten wie XML.
Das behandeln wir in unserem Workshop für Fortgeschrittene.&lt;/p>
&lt;hr>
&lt;p>Im nächsten Teil beschäftigen wir uns mit den Mechanismen zum Clustering in OpenRefine.&lt;/p>
&lt;ul class="cta-group">
&lt;li>
&lt;a href="https://fdmlab.landesarchiv-bw.de/workshop/openrefine-einsteiger/05-clustering" class="btn btn-primary px-3 py-3">05 Daten mit OpenRefine clustern&lt;/a>
&lt;/li>
&lt;/ul></description></item><item><title>Workshop - Projekte in OpenRefine laden und verwalten</title><link>https://fdmlab.landesarchiv-bw.de/workshop/openrefine-einsteiger/01-projekte-laden/</link><pubDate>Fri, 01 Apr 2022 00:00:00 +0000</pubDate><guid>https://fdmlab.landesarchiv-bw.de/workshop/openrefine-einsteiger/01-projekte-laden/</guid><description>&lt;p>Wir laden mehrere Dateien in OpenRefine Projekte und bearbeiten deren Metadaten.&lt;/p>
&lt;blockquote>
&lt;p>Projekte in der &lt;a href="https://docs.openrefine.org/manual/starting" target="_blank" rel="noopener">OpenRefine Dokumentation&lt;/a>.&lt;/p>
&lt;/blockquote>
&lt;div class="alert alert-note">
Dieser Workshop wurde erstellt mit OpenRefine Version 3.5.0.&lt;br>
Dieser Workshop wurde zuletzt getestet mit OpenRefine Version &lt;strong>3.9.3&lt;/strong>.
&lt;/div>
&lt;h2 id="hintergrund">Hintergrund&lt;/h2>
&lt;p>OpenRefine kann unterschiedliche Dateiformate über verschiedene Quellen in das interne Projektformat importieren. Der &amp;ldquo;übliche&amp;rdquo; Weg ist der Import von einer oder mehreren Dateien, weshalb wir uns vorerst darauf beschränken.&lt;/p>
&lt;h2 id="aufgabe-1-eine-datei-laden">Aufgabe 1: Eine Datei laden&lt;/h2>
&lt;p>Wir werden im Laufe des Workshops häufiger mit einem &lt;strong>Ausschnitt&lt;/strong> der &lt;a href="https://www.landesarchiv-bw.de/de/aktuelles/nachrichten/73495" target="_blank" rel="noopener">Gurs-Deportationsliste&lt;/a> arbeiten, die vom &lt;a href="https://www.landesarchiv-bw.de/de/aktuelles/nachrichten/71420" target="_blank" rel="noopener">Generallandesarchiv Karlsruhe recherchiert&lt;/a> und im FDMLab bereinigt und mit weiteren Normdaten ergänzt wurde.&lt;/p>
&lt;p>Für diesen Workshop wurde die Liste nachträglich mit einigen &amp;ldquo;Problemen&amp;rdquo; versehen, die wir in den nachfolgenden Aufgaben bereinigen werden.
Für diese Aufgabe wollen wir erst einmal nur die Datei &lt;code>01_gurs.csv&lt;/code> in das Projekt &amp;ldquo;Gurs&amp;rdquo; laden.&lt;/p>
&lt;blockquote>
&lt;p>💾 Wir benötigen die folgende Datei (Rechtsklick und &amp;ldquo;Ziel speichern unter&amp;hellip;&amp;rdquo;):&lt;/p>
&lt;/blockquote>
&lt;a href="https://fdmlab.landesarchiv-bw.de/data/openrefine-workshop/01_gurs.csv" target="_blank">
&lt;i class="fas fa-file-csv pr-1 fa-fw">&lt;/i>Gurs als CSV&lt;/a>
&lt;p>Beim Projektimport verwenden wir die folgenden Einstellungen:&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Project name&lt;/strong>: Gurs&lt;/li>
&lt;li>&lt;strong>Tags&lt;/strong>: Gurs, GND, Workshop, 2024&lt;/li>
&lt;/ul>
&lt;p>Die Optionen für das Format sind als Bildschirmfoto hinterlegt.&lt;/p>
&lt;figure id="figure-bildschirmfoto-von-openrefine-parsing-options">
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="Bildschirmfoto von OpenRefine Parsing Options." srcset="
/workshop/openrefine-einsteiger/01-projekte-laden/screenshot_openrefine_project_gurs_settings_hu60621eac040320a9ad6fb0b2765fc562_30441_34e175f2d0ab23d34c3d99487b07883e.webp 400w,
/workshop/openrefine-einsteiger/01-projekte-laden/screenshot_openrefine_project_gurs_settings_hu60621eac040320a9ad6fb0b2765fc562_30441_483613f4efeb23895037daa7ea94ce6a.webp 760w,
/workshop/openrefine-einsteiger/01-projekte-laden/screenshot_openrefine_project_gurs_settings_hu60621eac040320a9ad6fb0b2765fc562_30441_1200x1200_fit_q75_h2_lanczos_3.webp 1200w"
src="https://fdmlab.landesarchiv-bw.de/workshop/openrefine-einsteiger/01-projekte-laden/screenshot_openrefine_project_gurs_settings_hu60621eac040320a9ad6fb0b2765fc562_30441_34e175f2d0ab23d34c3d99487b07883e.webp"
width="760"
height="207"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;figcaption data-pre="Abbildung&amp;nbsp;" data-post=":&amp;nbsp;" class="numbered">
Bildschirmfoto von OpenRefine Parsing Options.
&lt;/figcaption>&lt;/figure>
&lt;div class="alert alert-warning">
&lt;div>
Die Gurs-Daten wurden zur Veröffentlichung im Blog aufbereitet, indem Zeilen und Spalten gelöscht sowie die restlichen Spalten zufällig sortiert wurden. Für die Verwendung in den Aufgaben des Workshops ist die Datei nach wie vor geeignet, jedoch &lt;strong>nicht&lt;/strong> für Recherche und Forschungszwecke!
&lt;/div>
&lt;/div>
&lt;h2 id="aufgabe-2-mehrere-dateien-gleichzeitig-laden">Aufgabe 2: Mehrere Dateien gleichzeitig laden&lt;/h2>
&lt;p>Wir haben die Beteiligten des &lt;a href="https://de.wikipedia.org/wiki/Kabinett_Kretschmann_III" target="_blank" rel="noopener">Kabinetts Kretschmann III&lt;/a> getrennt nach Frauen und Männern in zwei CSV Dateien gespeichert (&lt;code>01_kretschmann-kabinett-frauen.csv&lt;/code> und &lt;code>01_kretschmann-kabinett-maenner.csv&lt;/code>).&lt;/p>
&lt;blockquote>
&lt;p>💾 Wir benötigen die folgenden zwei Dateien (Rechtsklick und &amp;ldquo;Ziel speichern unter&amp;hellip;&amp;rdquo;):&lt;/p>
&lt;/blockquote>
&lt;a href="https://fdmlab.landesarchiv-bw.de/data/openrefine-workshop/01_kretschmann-kabinett-frauen.csv" target="_blank">
&lt;i class="fas fa-file-csv pr-1 fa-fw">&lt;/i>Kretschmann Kabinett Frauen als CSV&lt;/a>
&lt;blockquote>
&lt;/blockquote>
&lt;a href="https://fdmlab.landesarchiv-bw.de/data/openrefine-workshop/01_kretschmann-kabinett-maenner.csv" target="_blank">
&lt;i class="fas fa-file-csv pr-1 fa-fw">&lt;/i>Kretschmann Kabinett Maenner als CSV&lt;/a>
&lt;p>Diese Dateien laden wir gemeinsam in ein OpenRefine Projekt.&lt;/p>
&lt;p>Beim Projektimport verwenden wir die folgenden Einstellungen:&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Project name&lt;/strong>: Kretschmann Kabinett III&lt;/li>
&lt;li>&lt;strong>Tags&lt;/strong>: GND, Workshop, 2024&lt;/li>
&lt;/ul>
&lt;p>Die Optionen für das Format sind als Bildschirmfoto hinterlegt.&lt;/p>
&lt;figure id="figure-bildschirmfoto-von-openrefine-parsing-options">
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="Bildschirmfoto von OpenRefine Parsing Options." srcset="
/workshop/openrefine-einsteiger/01-projekte-laden/screenshot_openrefine_project_kretschmann_settings_hu8224cd6c68e4b146c149cfc50ced7396_28906_1b3f025ec667f3cf1990b6febe70abc8.webp 400w,
/workshop/openrefine-einsteiger/01-projekte-laden/screenshot_openrefine_project_kretschmann_settings_hu8224cd6c68e4b146c149cfc50ced7396_28906_d4d87b5c79418c601a15e8a412987a48.webp 760w,
/workshop/openrefine-einsteiger/01-projekte-laden/screenshot_openrefine_project_kretschmann_settings_hu8224cd6c68e4b146c149cfc50ced7396_28906_1200x1200_fit_q75_h2_lanczos_3.webp 1200w"
src="https://fdmlab.landesarchiv-bw.de/workshop/openrefine-einsteiger/01-projekte-laden/screenshot_openrefine_project_kretschmann_settings_hu8224cd6c68e4b146c149cfc50ced7396_28906_1b3f025ec667f3cf1990b6febe70abc8.webp"
width="760"
height="190"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;figcaption data-pre="Abbildung&amp;nbsp;" data-post=":&amp;nbsp;" class="numbered">
Bildschirmfoto von OpenRefine Parsing Options.
&lt;/figcaption>&lt;/figure>
&lt;h2 id="aufgabe-3-projektdaten-anpassen">Aufgabe 3: Projektdaten anpassen&lt;/h2>
&lt;p>OpenRefine bietet noch mehr Einstellungen für Projekte, als die die wir beim Erstellen angeben.
Dazu gehören zum Beispiel der Name des Erstellers, ein Vorschaubild, die Lizenz, &amp;hellip;&lt;/p>
&lt;figure id="figure-bildschirmfoto-von-openrefine-projekt-metadaten">
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="Bildschirmfoto von OpenRefine Projekt Metadaten." srcset="
/workshop/openrefine-einsteiger/01-projekte-laden/screenshot_openrefine_project_gurs_metadata_hu0287b496007f4faea312a1fe2572f240_7262_8cda4d3b058e1761940f225c068f2116.webp 400w,
/workshop/openrefine-einsteiger/01-projekte-laden/screenshot_openrefine_project_gurs_metadata_hu0287b496007f4faea312a1fe2572f240_7262_9a2dc1802451126798412245a04b5ed3.webp 760w,
/workshop/openrefine-einsteiger/01-projekte-laden/screenshot_openrefine_project_gurs_metadata_hu0287b496007f4faea312a1fe2572f240_7262_1200x1200_fit_q75_h2_lanczos_3.webp 1200w"
src="https://fdmlab.landesarchiv-bw.de/workshop/openrefine-einsteiger/01-projekte-laden/screenshot_openrefine_project_gurs_metadata_hu0287b496007f4faea312a1fe2572f240_7262_8cda4d3b058e1761940f225c068f2116.webp"
width="760"
height="49"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;figcaption data-pre="Abbildung&amp;nbsp;" data-post=":&amp;nbsp;" class="numbered">
Bildschirmfoto von OpenRefine Projekt Metadaten.
&lt;/figcaption>&lt;/figure>
&lt;p>Um diese anzupassen, verwendet man den Link &amp;ldquo;About&amp;rdquo; in der Projektübersicht wie in Abbildung 3 und fügt die Informationen via &amp;ldquo;Edit&amp;rdquo; ein.
Um dies einmal durchzuführen, ergänzen wir bei dem Gurs-Projekt im Feld &lt;em>Homepage&lt;/em> die URL des LABW, wie in Abbildung 4 gezeigt.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-plain" data-lang="plain">&lt;span class="line">&lt;span class="cl">https://www.landesarchiv-bw.de
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
&lt;figure id="figure-bildschirmfoto-von-dem-bearbeitungsdialog-der-openrefine-projekt-metadaten">
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="Bildschirmfoto von dem Bearbeitungsdialog der OpenRefine Projekt Metadaten." srcset="
/workshop/openrefine-einsteiger/01-projekte-laden/screenshot_openrefine_project_gurs_metadata_edit_hue766fd0ec3f66ea47a58be41ff649efc_48851_fce0e27a657b8fe22d038d5b91ba346e.webp 400w,
/workshop/openrefine-einsteiger/01-projekte-laden/screenshot_openrefine_project_gurs_metadata_edit_hue766fd0ec3f66ea47a58be41ff649efc_48851_4f553f7719efd1f4828aee1af79523c2.webp 760w,
/workshop/openrefine-einsteiger/01-projekte-laden/screenshot_openrefine_project_gurs_metadata_edit_hue766fd0ec3f66ea47a58be41ff649efc_48851_1200x1200_fit_q75_h2_lanczos_3.webp 1200w"
src="https://fdmlab.landesarchiv-bw.de/workshop/openrefine-einsteiger/01-projekte-laden/screenshot_openrefine_project_gurs_metadata_edit_hue766fd0ec3f66ea47a58be41ff649efc_48851_fce0e27a657b8fe22d038d5b91ba346e.webp"
width="760"
height="495"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;figcaption data-pre="Abbildung&amp;nbsp;" data-post=":&amp;nbsp;" class="numbered">
Bildschirmfoto von dem Bearbeitungsdialog der OpenRefine Projekt Metadaten.
&lt;/figcaption>&lt;/figure>
&lt;h2 id="aufgabe-4-aktionsverlauf">Aufgabe 4: Aktionsverlauf&lt;/h2>
&lt;p>OpenRefine speichert Änderungen automatisch und erstellt einen Verlauf aller auf ein Projekt angewendeter Aktionen.
Diese können im Tab &amp;ldquo;Undo/Redo&amp;rdquo; angesehen, rückgängig gemacht oder importiert werden.&lt;/p>
&lt;p>Um das besser kennen zu lernen laden wir ein OpenRefine Projekt und übertragen die Änderungshistorie auf ein Projekt von uns.&lt;/p>
&lt;blockquote>
&lt;p>💾 Wir benötigen die folgende Datei (Rechtsklick und &amp;ldquo;Ziel speichern unter&amp;hellip;&amp;rdquo;):&lt;/p>
&lt;/blockquote>
&lt;a href="https://fdmlab.landesarchiv-bw.de/data/openrefine-workshop/01_kretschmann-kabinett-iii-vorlage.openrefine.tar.gz" target="_blank">
&lt;i class="fas fa-file-zipper pr-1 fa-fw">&lt;/i>Kretschmann Kabinett (Vorlage) als OpenRefine Projektdatei&lt;/a>
&lt;p>Wir laden die OpenRefine Projektdatei über das in Abbildung 5 gezeigte Formular zum Importieren von OpenRefine Projekten.&lt;/p>
&lt;figure id="figure-bildschirmfoto-vom-formular-zum-importieren-von-openrefine-projekten">
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="Bildschirmfoto vom Formular zum Importieren von OpenRefine Projekten." srcset="
/workshop/openrefine-einsteiger/01-projekte-laden/screenshot-openrefine-project-import_hu8aac3b5e820504d1d1b06a13beec916d_15262_a5403a0e4948a623a8da26eb65f9792d.webp 400w,
/workshop/openrefine-einsteiger/01-projekte-laden/screenshot-openrefine-project-import_hu8aac3b5e820504d1d1b06a13beec916d_15262_5b82c1c49b90bd760db11f48194c6aa7.webp 760w,
/workshop/openrefine-einsteiger/01-projekte-laden/screenshot-openrefine-project-import_hu8aac3b5e820504d1d1b06a13beec916d_15262_1200x1200_fit_q75_h2_lanczos_3.webp 1200w"
src="https://fdmlab.landesarchiv-bw.de/workshop/openrefine-einsteiger/01-projekte-laden/screenshot-openrefine-project-import_hu8aac3b5e820504d1d1b06a13beec916d_15262_a5403a0e4948a623a8da26eb65f9792d.webp"
width="738"
height="177"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;figcaption data-pre="Abbildung&amp;nbsp;" data-post=":&amp;nbsp;" class="numbered">
Bildschirmfoto vom Formular zum Importieren von OpenRefine Projekten.
&lt;/figcaption>&lt;/figure>
&lt;p>Anschließend öffnen wir den Reiter für die Änderungshistorie in OpenRefine.
Dort werden automatisch alle automatisch gespeicherten Arbeitsschritte gezeigt.
Frühere Zustände des Projektes können durch Anklicken des entsprechenden Eintrages in der Änderungshistorie wiederhergestellt oder überschrieben werden.
Geht man in der Änderungshistorie zum Beispiel zu Schritt 2 zurück und fügt dann eine neue Änderung ein, dann werden die nachfolgenden Schritte (3-4) überschrieben.&lt;/p>
&lt;p>Wie in Abbildung 6 gezeigt können die Arbeitsschritte eines Projektes auch extrahiert werden.&lt;/p>
&lt;figure id="figure-bildschirmfoto-des-reiters-für-die-änderungshistorie-in-openrefine">
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="Bildschirmfoto des Reiters für die Änderungshistorie in OpenRefine." srcset="
/workshop/openrefine-einsteiger/01-projekte-laden/screenshot-openrefine-project-history_hu9b0394b8f2ce103a993c0493226ebd35_54539_044ef6d5cb2495d05a61b98791719c44.webp 400w,
/workshop/openrefine-einsteiger/01-projekte-laden/screenshot-openrefine-project-history_hu9b0394b8f2ce103a993c0493226ebd35_54539_14ee8984d054bf51b3d11538c209be17.webp 760w,
/workshop/openrefine-einsteiger/01-projekte-laden/screenshot-openrefine-project-history_hu9b0394b8f2ce103a993c0493226ebd35_54539_1200x1200_fit_q75_h2_lanczos_3.webp 1200w"
src="https://fdmlab.landesarchiv-bw.de/workshop/openrefine-einsteiger/01-projekte-laden/screenshot-openrefine-project-history_hu9b0394b8f2ce103a993c0493226ebd35_54539_044ef6d5cb2495d05a61b98791719c44.webp"
width="760"
height="390"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;figcaption data-pre="Abbildung&amp;nbsp;" data-post=":&amp;nbsp;" class="numbered">
Bildschirmfoto des Reiters für die Änderungshistorie in OpenRefine.
&lt;/figcaption>&lt;/figure>
&lt;p>Der in Abbildung 7 gezeigte Dialog zum Extrahieren erlaubt es auch einzelne Schritte zum Export aus- oder abzuwählen.
Wir extrahieren den kompletten Text und kopieren ihn in die Zwischenablage.&lt;/p>
&lt;figure id="figure-bildschirmfoto-des-dialogs-zum-extrahieren-von-änderungen">
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="Bildschirmfoto des Dialogs zum Extrahieren von Änderungen." srcset="
/workshop/openrefine-einsteiger/01-projekte-laden/screenshot-openrefine-project-history-extract_hu5bb3a1676ba07aa9a94c00a9087975ac_37591_015f44628c2fd6dc7a9a05d4c71b8aa1.webp 400w,
/workshop/openrefine-einsteiger/01-projekte-laden/screenshot-openrefine-project-history-extract_hu5bb3a1676ba07aa9a94c00a9087975ac_37591_47c8d7363e0947dfea847718251852a2.webp 760w,
/workshop/openrefine-einsteiger/01-projekte-laden/screenshot-openrefine-project-history-extract_hu5bb3a1676ba07aa9a94c00a9087975ac_37591_1200x1200_fit_q75_h2_lanczos_3.webp 1200w"
src="https://fdmlab.landesarchiv-bw.de/workshop/openrefine-einsteiger/01-projekte-laden/screenshot-openrefine-project-history-extract_hu5bb3a1676ba07aa9a94c00a9087975ac_37591_015f44628c2fd6dc7a9a05d4c71b8aa1.webp"
width="760"
height="577"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;figcaption data-pre="Abbildung&amp;nbsp;" data-post=":&amp;nbsp;" class="numbered">
Bildschirmfoto des Dialogs zum Extrahieren von Änderungen.
&lt;/figcaption>&lt;/figure>
&lt;p>Der kopierte Text sieht in etwa wie folgt aus, wobei die Beschreibung (&lt;em>description&lt;/em>) nachträglich mit einer deutschsprachigen Erklärung versehen wurde.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-json" data-lang="json">&lt;span class="line">&lt;span class="cl">&lt;span class="p">[&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;op&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;core/column-split&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;engineConfig&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;facets&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">[],&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;mode&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;row-based&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;columnName&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;Bevorzugter Name&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;guessCellType&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="kc">true&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;removeOriginalColumn&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="kc">true&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;mode&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;separator&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;separator&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;,&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;regex&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="kc">false&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;maxColumns&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="mi">2&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;description&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;Spalte nach Vorname und Nachname auftrennen.&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;op&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;core/column-rename&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;oldColumnName&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;Bevorzugter Name 1&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;newColumnName&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;Nachname&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;description&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;Spalte Bevorzugter Name 1 in Nachname umbenennen.&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;op&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;core/column-rename&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;oldColumnName&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;Bevorzugter Name 2&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;newColumnName&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;Vorname&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;description&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;Spalte Bevorzugter Name 2 in Vorname umbenennen.&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;op&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;core/text-transform&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;engineConfig&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;facets&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">[],&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;mode&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;row-based&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;columnName&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;Geschlecht&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;expression&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;grel:if(value == \&amp;#34;Weiblich\&amp;#34;, \&amp;#34;w\&amp;#34;, \&amp;#34;m\&amp;#34;)&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;onError&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;keep-original&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;repeat&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="kc">false&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;repeatCount&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="mi">10&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;description&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;Männlich und Weiblich als m und w kodieren.&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Um die Änderungen in unserem eigenen Projekt anzuwenden öffnen wir das Projekt &amp;ldquo;Kretschmann Kabinett III&amp;rdquo;, öffnen dort den Tab &amp;ldquo;Undo/Redo&amp;rdquo;, drücken auf &amp;ldquo;Apply&amp;rdquo; und kopieren wie in Abbildung 8 den Text in den Dialog.&lt;/p>
&lt;figure id="figure-anwenden-von-aktionen-über-die-history-funktion-von-openrefine">
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="Anwenden von Aktionen über die History Funktion von OpenRefine." srcset="
/workshop/openrefine-einsteiger/01-projekte-laden/screenshot_openrefine_apply_history_hu63b2e3056be6bd66a529ba8f252b2a8a_60003_c785ec4c48ca44010ae7c8638ba661f1.webp 400w,
/workshop/openrefine-einsteiger/01-projekte-laden/screenshot_openrefine_apply_history_hu63b2e3056be6bd66a529ba8f252b2a8a_60003_1ec7892b98a8640862d8b479394f7660.webp 760w,
/workshop/openrefine-einsteiger/01-projekte-laden/screenshot_openrefine_apply_history_hu63b2e3056be6bd66a529ba8f252b2a8a_60003_1200x1200_fit_q75_h2_lanczos_3.webp 1200w"
src="https://fdmlab.landesarchiv-bw.de/workshop/openrefine-einsteiger/01-projekte-laden/screenshot_openrefine_apply_history_hu63b2e3056be6bd66a529ba8f252b2a8a_60003_c785ec4c48ca44010ae7c8638ba661f1.webp"
width="760"
height="569"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;figcaption data-pre="Abbildung&amp;nbsp;" data-post=":&amp;nbsp;" class="numbered">
Anwenden von Aktionen über die History Funktion von OpenRefine.
&lt;/figcaption>&lt;/figure>
&lt;p>Da wir in unserem Projekt die gleichen Spaltennamen haben, wie im Vorlagenprojekt, konnten wir die Änderungen direkt übernehmen und haben nun den gleichen Stand.&lt;/p>
&lt;h2 id="fazit">Fazit&lt;/h2>
&lt;p>OpenRefine öffnet viele unterschiedliche Dateitypen, extrahiert Archive, rät die Einstellungen für den Import und bietet mit der Vorschau eine tolle Möglichkeit die Einstellungen anzupassen. Das Metadatenmanagement der Projekte ist etwas lieblos implementiert.
Die Möglichkeit (fast) jeden Bearbeitungsschritt wieder rückgängig zu machen gibt die Sicherheit, auch mal Datenbearbeitungen ausprobieren zu können, ohne sich in verschiedenen Versionen einer &amp;ldquo;Datei&amp;rdquo; zu verlaufen. Beim Verlauf der Bearbeitungsschritte wäre es noch praktisch, wenn man verschiedene Stände markieren könnte, um schneller dorthin zurückzuspringen.&lt;/p>
&lt;hr>
&lt;p>Im nächsten Teil lernen wir, wie wir Daten in OpenRefine filtern und sortieren können.&lt;/p>
&lt;ul class="cta-group">
&lt;li>
&lt;a href="https://fdmlab.landesarchiv-bw.de/workshop/openrefine-einsteiger/02-filtern-und-sortieren" class="btn btn-primary px-3 py-3">02 Daten mit OpenRefine filtern und sortieren&lt;/a>
&lt;/li>
&lt;/ul></description></item><item><title>Gemeinsam an OpenRefine-Projekten arbeiten</title><link>https://fdmlab.landesarchiv-bw.de/post/2021-12-gemeinsam-an-openrefine-projekten-arbeiten/</link><pubDate>Tue, 07 Dec 2021 00:00:00 +0000</pubDate><guid>https://fdmlab.landesarchiv-bw.de/post/2021-12-gemeinsam-an-openrefine-projekten-arbeiten/</guid><description>&lt;p>Im FDMLab testeten wir verschiedene Möglichkeiten mit OpenRefine gemeinsam an Projekten zu arbeiten.
Dieser Artikel fasst unsere Erfahrungen beim kollaborativen Arbeiten mit OpenRefine 3.5.0 zusammen.&lt;/p>
&lt;p>Wir hatten in
&lt;a href="https://fdmlab.landesarchiv-bw.de/post/2021-09-fuenf-dinge-die-wir-an-openrefine-moegen/">Fünf Dinge, die wir an OpenRefine mögen&lt;/a>
schon darüber berichtet, dass uns die Architektur von OpenRefine gefällt,
da sie es ermöglicht OpenRefine sowohl auf einem Client (Laptop, Rechner), als auch auf einem Server laufen zu lassen.
Die Bedienung erfolgt anschließend über den Browser.&lt;/p>
&lt;div class="mermaid">---
title: OpenRefine Setup
config:
look: handDrawn
theme: neutral
---
flowchart LR
subgraph server[fas:fa-server Server]
server_or[fas:fa-gem OpenRefine]
end
subgraph laptop[fas:fa-laptop Laptop]
browser[far:fa-window-maximize Browser]
laptop_or[fas:fa-gem OpenRefine]
end
browser -.-> laptop_or &amp; server_or
&lt;/div>
&lt;p>Da läge es nahe, dass OpenRefine auch eine Benutzerverwaltung und eine Möglichkeit zum Kollaborativen Arbeiten an Projekten anbietet.
Dafür gab es Pläne ein &lt;a href="https://github.com/OpenRefine/OpenRefine/wiki/Broker-Protocol" target="_blank" rel="noopener">Broker Protokoll für OpenRefine&lt;/a> einzuführen, die bisher aber weder umgesetzt noch eingeplant wurden.&lt;/p>
&lt;p>In der &lt;a href="https://docs.openrefine.org/" target="_blank" rel="noopener">Dokumentation von OpenRefine&lt;/a> wird folgendes Vorgehen empfohlen:&lt;/p>
&lt;blockquote>
&lt;p>Die beste Art, mit einer anderen Person zusammenzuarbeiten, ist, Projekte zu exportieren und zu importieren, wobei alle Änderungen gespeichert werden, so dass Sie an der Stelle weiterarbeiten können, wo die andere Person aufgehört hat.&lt;/p>
&lt;p>Übersetzt von &lt;a href="https://docs.openrefine.org/manual/starting#import-a-project" target="_blank" rel="noopener">Starting a project: Import a project&lt;/a>, aufgerufen am 01.12.2021.&lt;/p>
&lt;/blockquote>
&lt;div class="mermaid">---
title: Gemeinsam arbeiten - Strategie 1
config:
look: handDrawn
theme: neutral
---
flowchart TD
subgraph a["fa:fa-user Alice"]
vaa["fa:fa-table Version A"]
vab["fa:fa-table Version B"]
vac["fa:fa-table Version C"]
vad["fa:fa-table Version D"]
end
subgraph b["fa:fa-user Bob"]
vba["fa:fa-table Version A"]
vbb["fa:fa-table Version B"]
end
subgraph c["fa:fa-user Charly"]
vcb["fa:fa-table Version B"]
vcc["fa:fa-table Version C"]
end
vaa -.Übergabe.-> vba --Arbeiten--> vbb -.Übergabe.-> vab -.Übergabe.-> vcb --Arbeiten--> vcc -.Übergabe.-> vac --Arbeiten--> vad
&lt;/div>
&lt;p>Konkret bedeutet das, dass bei einer Kooperation von Alice, Bob und Charly zwar alle an dem gleichen Projekt arbeiten können, jedoch nicht gleichzeitig. Nachdem Alice das Projekt an Bob übergeben hat, arbeitet Bob daran. Nachdem Bob fertig ist, übergibt er das Projekt an Alice zurück, die es an Charly übergibt. Nachdem Charly fertig ist, übergibt er das Projekt an Alice zurück,
die dann erst daran weiterarbeiten kann.
Das war für uns im FDMLab ein eher unbefriedigender Zustand, weshalb wir zu einer anderen Strategie gewechselt haben.&lt;/p>
&lt;div class="mermaid">---
title: Gemeinsam Arbeiten - Strategie 2
config:
look: handDrawn
theme: neutral
---
flowchart LR
subgraph a["fa:fa-user Alice"]
va["fa:fa-table Version A"]
vb["fa:fa-table Version B"]
vc["fa:fa-table Version C"]
vd["fa:fa-table Version D"]
end
subgraph b["fa:fa-user Bob"]
pa["fa:fa-table Part A"]
end
subgraph c["fa:fa-user Charly"]
pb["fa:fa-table Part B"]
end
va -.-> pa
vb -.-> pb
pa -.-> vc
pb -.-> vd
va --Arbeiten--> vb --Arbeiten--> vc --Arbeiten--> vd
&lt;/div>
&lt;p>Wir haben angefangen Teile eines Projektes in OpenRefine auszulagern und nach erfolgreicher Bearbeitung wieder in das Originalprojekt einzupflegen.
So kann in unserem Beispiel Alice weiter an dem Projekt arbeiten, während Bob und Charly sie durch die Bearbeitung einzelner Teile unterstützen. Diese Teile werden anschließend von Alice wieder in das Originalprojekt eingepflegt.
Wie das funktioniert besprechen wir in den folgenden Unterpunkten.&lt;/p>
&lt;h2 id="zeilenweise-zusammenführen">Zeilenweise zusammenführen&lt;/h2>
&lt;p>Manchmal ist es möglich, ein Projekt zeilenweise aufzuteilen. Also dass Alice die ersten 100 Zeilen, Bob die nächsten 100 und Charly die letzten 75 Zeilen bearbeitet.&lt;/p>
&lt;p>Die Ergebnisse können nach der Bearbeitung als CSV-Dateien exportiert und daraus anschließend ein neues OpenRefine-Projekt erstellt werden.&lt;/p>
&lt;figure id="figure-bildschirmfoto-der-dateiauswahl-oberfläche-von-openrefine">
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="Bildschirmfoto der Dateiauswahl Oberfläche von OpenRefine." srcset="
/post/2021-12-gemeinsam-an-openrefine-projekten-arbeiten/screenshot-openrefine-create-multiple-1_hu402989673ec7c7ca2e68b32580c83e60_3527_f8f279f4f94d7c5e8446255ac0f8e90a.webp 400w,
/post/2021-12-gemeinsam-an-openrefine-projekten-arbeiten/screenshot-openrefine-create-multiple-1_hu402989673ec7c7ca2e68b32580c83e60_3527_6bff2ecacd8694f256793a04bf94172b.webp 760w,
/post/2021-12-gemeinsam-an-openrefine-projekten-arbeiten/screenshot-openrefine-create-multiple-1_hu402989673ec7c7ca2e68b32580c83e60_3527_1200x1200_fit_q75_h2_lanczos_3.webp 1200w"
src="https://fdmlab.landesarchiv-bw.de/post/2021-12-gemeinsam-an-openrefine-projekten-arbeiten/screenshot-openrefine-create-multiple-1_hu402989673ec7c7ca2e68b32580c83e60_3527_f8f279f4f94d7c5e8446255ac0f8e90a.webp"
width="304"
height="77"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;figcaption data-pre="Abbildung&amp;nbsp;" data-post=":&amp;nbsp;" class="numbered">
Bildschirmfoto der Dateiauswahl Oberfläche von OpenRefine.
&lt;/figcaption>&lt;/figure>
&lt;p>Wie in Abbildung 1 gezeigt, kann OpenRefine ein Projekt aus mehreren Dateien erstellen.
Das kann auch ein Dateiarchiv sein, dessen Dateien in ein neues Projekt importiert werden.&lt;/p>
&lt;figure id="figure-bildschirmfoto-des-dateifilter-oberfläche-von-openrefine">
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="Bildschirmfoto des Dateifilter Oberfläche von OpenRefine." srcset="
/post/2021-12-gemeinsam-an-openrefine-projekten-arbeiten/screenshot-openrefine-create-multiple-2_hu632d044bc7e37669654237939b6eb031_22723_1399221371f58cd8b77ea03867927303.webp 400w,
/post/2021-12-gemeinsam-an-openrefine-projekten-arbeiten/screenshot-openrefine-create-multiple-2_hu632d044bc7e37669654237939b6eb031_22723_fabc96d2b52b33acf2c43c94a595e0fd.webp 760w,
/post/2021-12-gemeinsam-an-openrefine-projekten-arbeiten/screenshot-openrefine-create-multiple-2_hu632d044bc7e37669654237939b6eb031_22723_1200x1200_fit_q75_h2_lanczos_3.webp 1200w"
src="https://fdmlab.landesarchiv-bw.de/post/2021-12-gemeinsam-an-openrefine-projekten-arbeiten/screenshot-openrefine-create-multiple-2_hu632d044bc7e37669654237939b6eb031_22723_1399221371f58cd8b77ea03867927303.webp"
width="760"
height="167"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;figcaption data-pre="Abbildung&amp;nbsp;" data-post=":&amp;nbsp;" class="numbered">
Bildschirmfoto des Dateifilter Oberfläche von OpenRefine.
&lt;/figcaption>&lt;/figure>
&lt;p>Bevor das Projekt konfiguriert wird, gibt es wie in Abbildung 2 gezeigt, die Möglichkeit einzelne Dateien aus- oder abzuwählen.
Im Idealfall haben die einzelnen Dateien schon die gleichen Spaltenüberschriften in der richtigen Reihenfolge.
Ansonsten bietet OpenRefine mit der Möglichkeit &lt;a href="https://docs.openrefine.org/manual/columnediting#join-columns" target="_blank" rel="noopener">Spalten zu verbinden&lt;/a> und &lt;a href="https://docs.openrefine.org/manual/columnediting#renaming-removing-and-moving" target="_blank" rel="noopener">Spalten zu verschieben&lt;/a> die Möglichkeit das nachträglich zu bereinigen.&lt;/p>
&lt;h2 id="spaltenweise-zusammenführen">Spaltenweise zusammenführen&lt;/h2>
&lt;p>Ein häufiger Anwendungsfall im FDMLab ist, dass das Aufräumen und Transformieren der Daten von einer Person erledigt wird, die zum Beispiel beim Reconciling oder dem Abgleich mit weiteren Datenquellen von weiteren Personen unterstützt wird. Dafür werden einzelne Spalten als CSV (oder Excel) exportiert, von der unterstützenden Person bearbeitet und die Ergebnisse dann wieder in das Originalprojekt übernommen.&lt;/p>
&lt;p>Ein anderer Fall kann sein, dass es schon einen anderen Datensatz gibt, dessen Daten komplett oder teilweise übernommen werden sollen.
Das haben wir in &lt;a href="https://fdmlab.landesarchiv-bw.de/post/2021-08-findbuch-daten-mit-openrefine-wiederverwenden/">Findbuchdaten mit OpenRefine wiederverwenden&lt;/a> teilweise besprochen.&lt;/p>
&lt;h3 id="beispiel">Beispiel&lt;/h3>
&lt;p>In unserem fiktiven Beispiel arbeitet Alice mit einem Datensatz der 16 Bundesländer, wie er in Abbildung 3 gezeigt ist.
Diesen gibt sie an Bob und Charly weiter.&lt;/p>
&lt;figure id="figure-bildschirmfoto-der-oberfläche-von-openrefine-mit-den-16-bundesländern">
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="Bildschirmfoto der Oberfläche von OpenRefine mit den 16 Bundesländern." srcset="
/post/2021-12-gemeinsam-an-openrefine-projekten-arbeiten/screenshot-openrefine-bundeslaender_hu834d87ba914778413fda02e8c0d2c96a_13980_40dbfda5bc30f47578f1087796953bee.webp 400w,
/post/2021-12-gemeinsam-an-openrefine-projekten-arbeiten/screenshot-openrefine-bundeslaender_hu834d87ba914778413fda02e8c0d2c96a_13980_40fbe0ec9c8e7474c5eba9551e95a797.webp 760w,
/post/2021-12-gemeinsam-an-openrefine-projekten-arbeiten/screenshot-openrefine-bundeslaender_hu834d87ba914778413fda02e8c0d2c96a_13980_1200x1200_fit_q75_h2_lanczos_3.webp 1200w"
src="https://fdmlab.landesarchiv-bw.de/post/2021-12-gemeinsam-an-openrefine-projekten-arbeiten/screenshot-openrefine-bundeslaender_hu834d87ba914778413fda02e8c0d2c96a_13980_40dbfda5bc30f47578f1087796953bee.webp"
width="226"
height="367"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;figcaption data-pre="Abbildung&amp;nbsp;" data-post=":&amp;nbsp;" class="numbered">
Bildschirmfoto der Oberfläche von OpenRefine mit den 16 Bundesländern.
&lt;/figcaption>&lt;/figure>
&lt;p>Bob unterstützt Alice, indem er für die 16 Bundesländer das &amp;ldquo;Motto&amp;rdquo; recherchiert, er kann jedoch nicht für alle Bundesländer ein Motto finden und liefert den in Abbildung 4 gezeigten Datensatz zurück. &lt;sup id="fnref:1">&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref">1&lt;/a>&lt;/sup>&lt;/p>
&lt;figure id="figure-bildschirmfoto-der-oberfläche-von-openrefine-mit-dem-motto-einiger-bundesländer">
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="Bildschirmfoto der Oberfläche von OpenRefine mit dem Motto einiger Bundesländer." srcset="
/post/2021-12-gemeinsam-an-openrefine-projekten-arbeiten/screenshot-openrefine-bundeslaender-motto_hue850d04bcf76bdb2f02a1168cb267115_9708_e3618f764baaa0d2c91b126a4d9aefef.webp 400w,
/post/2021-12-gemeinsam-an-openrefine-projekten-arbeiten/screenshot-openrefine-bundeslaender-motto_hue850d04bcf76bdb2f02a1168cb267115_9708_d3434bad2b7cf904e687d49ae311e4d2.webp 760w,
/post/2021-12-gemeinsam-an-openrefine-projekten-arbeiten/screenshot-openrefine-bundeslaender-motto_hue850d04bcf76bdb2f02a1168cb267115_9708_1200x1200_fit_q75_h2_lanczos_3.webp 1200w"
src="https://fdmlab.landesarchiv-bw.de/post/2021-12-gemeinsam-an-openrefine-projekten-arbeiten/screenshot-openrefine-bundeslaender-motto_hue850d04bcf76bdb2f02a1168cb267115_9708_e3618f764baaa0d2c91b126a4d9aefef.webp"
width="372"
height="174"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;figcaption data-pre="Abbildung&amp;nbsp;" data-post=":&amp;nbsp;" class="numbered">
Bildschirmfoto der Oberfläche von OpenRefine mit dem Motto einiger Bundesländer.
&lt;/figcaption>&lt;/figure>
&lt;p>Charly hat die Aufgabe die Hauptstädte der einzelnen Bundesländer zu recherchieren, und liefert den in Abbildung 5 gezeigten Datensatz zurück. Dabei wurden jedoch die Namen der Bundesländer teilweise geändert, also zum Beispiel der Begriff &amp;ldquo;Freistaat&amp;rdquo; aus dem Namen wegoptimiert.&lt;/p>
&lt;figure id="figure-bildschirmfoto-der-oberfläche-von-openrefine-mit-den-hauptstädten-der-16-bundesländer">
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="Bildschirmfoto der Oberfläche von OpenRefine mit den Hauptstädten der 16 Bundesländer." srcset="
/post/2021-12-gemeinsam-an-openrefine-projekten-arbeiten/screenshot-openrefine-bundeslaender-hauptstadt_hudb6941757d764e7bc3df4946962e3922_15914_937e0ee52a239fc231180e731f64bfde.webp 400w,
/post/2021-12-gemeinsam-an-openrefine-projekten-arbeiten/screenshot-openrefine-bundeslaender-hauptstadt_hudb6941757d764e7bc3df4946962e3922_15914_5ded926aea1e6c28aa156d981867df94.webp 760w,
/post/2021-12-gemeinsam-an-openrefine-projekten-arbeiten/screenshot-openrefine-bundeslaender-hauptstadt_hudb6941757d764e7bc3df4946962e3922_15914_1200x1200_fit_q75_h2_lanczos_3.webp 1200w"
src="https://fdmlab.landesarchiv-bw.de/post/2021-12-gemeinsam-an-openrefine-projekten-arbeiten/screenshot-openrefine-bundeslaender-hauptstadt_hudb6941757d764e7bc3df4946962e3922_15914_937e0ee52a239fc231180e731f64bfde.webp"
width="297"
height="373"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;figcaption data-pre="Abbildung&amp;nbsp;" data-post=":&amp;nbsp;" class="numbered">
Bildschirmfoto der Oberfläche von OpenRefine mit den Hauptstädten der 16 Bundesländer.
&lt;/figcaption>&lt;/figure>
&lt;h3 id="datensätze-herunterladen">Datensätze herunterladen&lt;/h3>
&lt;p>Die drei beschriebenen Datensätze können hier heruntergeladen werden, um die vorgestellten Methoden zum Zusammenführen von Daten beim gemeinsamen Arbeiten in OpenRefine selbst auszuprobieren&lt;/p>
&lt;blockquote>
&lt;p>💾 Wir benötigen drei Dateien (Rechtsklick und &amp;ldquo;Ziel speichern unter&amp;hellip;&amp;rdquo;):&lt;/p>
&lt;/blockquote>
&lt;a href="https://fdmlab.landesarchiv-bw.de/data/bundeslaender/bundeslaender.csv" target="_blank">
&lt;i class="fas fa-file-csv pr-1 fa-fw">&lt;/i>Bundesländer als CSV&lt;/a>
&lt;blockquote>
&lt;/blockquote>
&lt;a href="https://fdmlab.landesarchiv-bw.de/data/bundeslaender/bundeslaender-motto.csv" target="_blank">
&lt;i class="fas fa-file-csv pr-1 fa-fw">&lt;/i>Bundesländer Motto als CSV&lt;/a>
&lt;blockquote>
&lt;/blockquote>
&lt;a href="https://fdmlab.landesarchiv-bw.de/data/bundeslaender/bundeslaender-hauptstadt.csv" target="_blank">
&lt;i class="fas fa-file-csv pr-1 fa-fw">&lt;/i>Bundesländer Hauptstädte als CSV&lt;/a>
&lt;h3 id="id-spalte-erstellen">ID Spalte erstellen&lt;/h3>
&lt;p>Wir werden die Daten auf drei Arten abgleichen:&lt;/p>
&lt;ol>
&lt;li>Via einer dedizierten ID-Spalte&lt;/li>
&lt;li>Mit einer improvisierten ID-Spalte (Name des Bundeslandes)&lt;/li>
&lt;li>Via Reconciling&lt;/li>
&lt;/ol>
&lt;p>Idealerweise haben alle Datensätze eine einheitliche ID-Spalte zum Abgleichen.
Diese lässt sich in OpenRefine über
&amp;ldquo;Spaltenmenü&amp;quot;
&lt;i class="far fa-caret-square-down pr-1 fa-fw">&lt;/i>&amp;quot;Edit column&amp;quot;
&lt;i class="fas fa-caret-right pr-1 fa-fw">&lt;/i>&amp;quot;Add column based on this column&amp;hellip;&amp;rdquo;
mit dem folgenden GREL Ausdruck anlegen:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="nx">row&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">index&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="mi">1&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Wie in Abbildung 6 gezeigt, wird so eine ID-Spalte erzeugt, deren Nummerierung analog zur Nummerierung der Zeilen in OpenRefine verläuft.&lt;/p>
&lt;figure id="figure-bildschirmfoto-des-spalten-hinzufügen-dialogs-in-openrefine">
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="Bildschirmfoto des Spalten hinzufügen Dialogs in OpenRefine." srcset="
/post/2021-12-gemeinsam-an-openrefine-projekten-arbeiten/screenshot-openrefine-dialog-add-id-col_hucd48aca33617d55cebd18e34c8369c9e_21645_259a34aa11dacb6cd88d12217fda7b0c.webp 400w,
/post/2021-12-gemeinsam-an-openrefine-projekten-arbeiten/screenshot-openrefine-dialog-add-id-col_hucd48aca33617d55cebd18e34c8369c9e_21645_b9e3e4c99d43a2fa57a52ad9239a711c.webp 760w,
/post/2021-12-gemeinsam-an-openrefine-projekten-arbeiten/screenshot-openrefine-dialog-add-id-col_hucd48aca33617d55cebd18e34c8369c9e_21645_1200x1200_fit_q75_h2_lanczos_3.webp 1200w"
src="https://fdmlab.landesarchiv-bw.de/post/2021-12-gemeinsam-an-openrefine-projekten-arbeiten/screenshot-openrefine-dialog-add-id-col_hucd48aca33617d55cebd18e34c8369c9e_21645_259a34aa11dacb6cd88d12217fda7b0c.webp"
width="721"
height="530"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;figcaption data-pre="Abbildung&amp;nbsp;" data-post=":&amp;nbsp;" class="numbered">
Bildschirmfoto des Spalten hinzufügen Dialogs in OpenRefine.
&lt;/figcaption>&lt;/figure>
&lt;p>Alternativ lassen sich manchmal auch ID-Spalten improvisieren, indem zum Beispiel bei Personen die Namen und Vornamen in eine ID-Spalte übernommen werden.&lt;/p>
&lt;h3 id="zusammenführen-mit-cross">Zusammenführen mit cross()&lt;/h3>
&lt;p>Alice hat von Bob und Charly zwei CSV-Dateien bekommen, die sie in ihr OpenRefine-Projekt übernehmen möchte.
Eine Möglichkeit, das innerhalb von OpenRefine zu erledigen, ist die Funktion
&lt;a href="https://docs.openrefine.org/manual/grelfunctions#crosscell-s-projectname-optional-s-columnname-optional" target="_blank" rel="noopener">cross()&lt;/a>.&lt;/p>
&lt;p>Im OpenRefine-Wiki gibt es einige
&lt;a href="https://github.com/OpenRefine/OpenRefine/wiki/Recipes#combining-datasets" target="_blank" rel="noopener">Beispiele zur Anwendung von cross()&lt;/a>.
Außerdem gibt es eine
&lt;a href="https://www.bits.vib.be/index.php/software-overview/openrefine" target="_blank" rel="noopener">OpenRefine-Erweiterung für cross()&lt;/a>
um die Funktion über Dialoge in der Oberfläche von OpenRefine zu verwenden.&lt;/p>
&lt;p>Wir verwenden die Funktion &lt;code>cross()&lt;/code> ohne Erweiterung. Dafür erstellen wir für die drei Datensätze jeweils ein Projekt.&lt;/p>
&lt;ol>
&lt;li>Projekt &amp;ldquo;Bundesländer&amp;rdquo; aus &lt;code>bundeslaender.csv&lt;/code>&lt;/li>
&lt;li>Projekt &amp;ldquo;Bundesländer Motto&amp;rdquo; aus &lt;code>bundeslaender-motto.csv&lt;/code>&lt;/li>
&lt;li>Projekt &amp;ldquo;Bundesländer Hauptstadt&amp;rdquo; aus &lt;code>bundeslaender-hauptstadt.csv&lt;/code>&lt;/li>
&lt;/ol>
&lt;div class="alert alert-info">
&lt;div>
Wir verwenden absichtlich Umlaute und Leerzeichen im Projektnamen, um zu testen, ob OpenRefine beim Auflösen mit &lt;code>cross()&lt;/code> damit klarkommt!
&lt;/div>
&lt;/div>
&lt;h4 id="zusammenführen-via-id">Zusammenführen via ID&lt;/h4>
&lt;p>Idealerweise haben wir eine eindeutige ID-Spalte, um die Projekte miteinander abzugleichen.
Mit &lt;code>cross()&lt;/code> können wir über die ID-Spalte Daten aus einem anderen OpenRefine-Projekt nachladen.
Das funktioniert aber nur, wenn die IDs eindeutig sind.&lt;/p>
&lt;h5 id="nachladen-des-mottos">Nachladen des Mottos&lt;/h5>
&lt;p>Zum Nachladen des Mottos der Bundesländer gehen wir im &amp;ldquo;Bundesländer&amp;rdquo;-Projekt über das Spaltenmenü
&amp;ldquo;ID&amp;quot;
&lt;i class="far fa-caret-square-down pr-1 fa-fw">&lt;/i>&amp;quot;Edit column&amp;quot;
&lt;i class="fas fa-caret-right pr-1 fa-fw">&lt;/i>&amp;quot;Add column based on this column&amp;hellip;&amp;rdquo;
und verwenden den folgenden GREL Ausdruck.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="nx">cell&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">cross&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;Bundesländer Motto&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;ID&amp;#34;&lt;/span>&lt;span class="p">).&lt;/span>&lt;span class="nx">cells&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s2">&amp;#34;Mottotext&amp;#34;&lt;/span>&lt;span class="p">].&lt;/span>&lt;span class="nx">value&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="mi">0&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Dabei ist &amp;ldquo;Bundesländer Motto&amp;rdquo; der Name des Projektes aus dem wir die Daten holen wollen,
und &amp;ldquo;ID&amp;rdquo; die ID-Spalte im Projekt &amp;ldquo;Bundesländer Motto&amp;rdquo;.&lt;/p>
&lt;figure id="figure-bildschirmfoto-des-spalten-hinzufügen-dialogs-mit-cross-für-den-mottotext-in-openrefine">
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="Bildschirmfoto des Spalten hinzufügen Dialogs mit cross() für den Mottotext in OpenRefine." srcset="
/post/2021-12-gemeinsam-an-openrefine-projekten-arbeiten/screenshot-openrefine-dialog-cross-motto-1_hu8d6c0de36e7c11eb9e61089c401f8c9e_20478_0d2a60105870bc4d5e6d1f15a6ecd3ff.webp 400w,
/post/2021-12-gemeinsam-an-openrefine-projekten-arbeiten/screenshot-openrefine-dialog-cross-motto-1_hu8d6c0de36e7c11eb9e61089c401f8c9e_20478_ee94f02329049b7f118eb1ad7acd41ed.webp 760w,
/post/2021-12-gemeinsam-an-openrefine-projekten-arbeiten/screenshot-openrefine-dialog-cross-motto-1_hu8d6c0de36e7c11eb9e61089c401f8c9e_20478_1200x1200_fit_q75_h2_lanczos_3.webp 1200w"
src="https://fdmlab.landesarchiv-bw.de/post/2021-12-gemeinsam-an-openrefine-projekten-arbeiten/screenshot-openrefine-dialog-cross-motto-1_hu8d6c0de36e7c11eb9e61089c401f8c9e_20478_0d2a60105870bc4d5e6d1f15a6ecd3ff.webp"
width="758"
height="537"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;figcaption data-pre="Abbildung&amp;nbsp;" data-post=":&amp;nbsp;" class="numbered">
Bildschirmfoto des Spalten hinzufügen Dialogs mit cross() für den Mottotext in OpenRefine.
&lt;/figcaption>&lt;/figure>
&lt;p>Wie in Abbildung 7 gezeigt, werden die Daten (also der Mottotext) aus dem anderen Projekt nachgeladen.
Es haben nicht alle Bundesländer einen Mottotext hinterlegt, was den Abgleich nicht weiter stört.&lt;/p>
&lt;h5 id="nachladen-der-hauptstadt">Nachladen der Hauptstadt&lt;/h5>
&lt;p>Zum Nachladen der Hauptstadt der Bundesländer gehen wir im &amp;ldquo;Bundesländer&amp;rdquo;-Projekt über das Spaltenmenü
&amp;ldquo;ID&amp;quot;
&lt;i class="far fa-caret-square-down pr-1 fa-fw">&lt;/i>&amp;quot;Edit column&amp;quot;
&lt;i class="fas fa-caret-right pr-1 fa-fw">&lt;/i>&amp;quot;Add column based on this column&amp;hellip;&amp;rdquo;
und verwenden den folgenden GREL Ausdruck.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="nx">cell&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">cross&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;Bundesländer Hauptstadt&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;ID&amp;#34;&lt;/span>&lt;span class="p">).&lt;/span>&lt;span class="nx">cells&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s2">&amp;#34;Hauptstadt&amp;#34;&lt;/span>&lt;span class="p">].&lt;/span>&lt;span class="nx">value&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="mi">0&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Dabei ist &amp;ldquo;Bundesländer Hauptstadt&amp;rdquo; der Name des Projektes aus dem wir die Daten holen wollen,
und &amp;ldquo;ID&amp;rdquo; die ID-Spalte im Projekt &amp;ldquo;Bundesländer Hauptstadt&amp;rdquo;.&lt;/p>
&lt;figure id="figure-bildschirmfoto-des-spalten-hinzufügen-dialogs-mit-cross-für-die-hauptstadt-in-openrefine">
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="Bildschirmfoto des Spalten hinzufügen Dialogs mit cross() für die Hauptstadt in OpenRefine." srcset="
/post/2021-12-gemeinsam-an-openrefine-projekten-arbeiten/screenshot-openrefine-dialog-cross-hauptstadt-1_hu7b7640fd7f81d9ef7172d608638c0551_21900_60af84c29669edd40e4bd0e8a97c0b0c.webp 400w,
/post/2021-12-gemeinsam-an-openrefine-projekten-arbeiten/screenshot-openrefine-dialog-cross-hauptstadt-1_hu7b7640fd7f81d9ef7172d608638c0551_21900_02cea76db379ba61cec116047373dad4.webp 760w,
/post/2021-12-gemeinsam-an-openrefine-projekten-arbeiten/screenshot-openrefine-dialog-cross-hauptstadt-1_hu7b7640fd7f81d9ef7172d608638c0551_21900_1200x1200_fit_q75_h2_lanczos_3.webp 1200w"
src="https://fdmlab.landesarchiv-bw.de/post/2021-12-gemeinsam-an-openrefine-projekten-arbeiten/screenshot-openrefine-dialog-cross-hauptstadt-1_hu7b7640fd7f81d9ef7172d608638c0551_21900_60af84c29669edd40e4bd0e8a97c0b0c.webp"
width="760"
height="537"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;figcaption data-pre="Abbildung&amp;nbsp;" data-post=":&amp;nbsp;" class="numbered">
Bildschirmfoto des Spalten hinzufügen Dialogs mit cross() für die Hauptstadt in OpenRefine.
&lt;/figcaption>&lt;/figure>
&lt;p>Wie in Abbildung 8 gezeigt, werden die Daten (hier die Hauptstadt) aus dem anderen Projekt nachgeladen.
Es haben alle Bundesländer eine Hauptstadt, so dass der Abgleich hier für jeden Eintrag ein Ergebnis produziert.&lt;/p>
&lt;p>Außerdem ist zu erwähnen, dass sich OpenRefine hier auch nicht daran stört, dass die ID-Spalte bei uns im Projekt &amp;ldquo;Bundesländer&amp;rdquo; als Zahl, im Projekt &amp;ldquo;Bundesländer Motto&amp;rdquo; jedoch als Typ Text gespeichert ist.&lt;/p>
&lt;h4 id="zusammenführen-via-werte">Zusammenführen via Werte&lt;/h4>
&lt;p>Es ist nicht immer eine eindeutige ID-Spalte vorhanden. Das kommt zum Beispiel vor, wenn die Daten aus verschiedenen Projekten stammen.
Man kann auch ID-Spalten improvisieren, was aber nicht immer zum gewünschten Ergebnis führt.
Wir werden den Abgleich mit &lt;code>cross()&lt;/code> diesmal über die Spalte &amp;ldquo;Bundesland&amp;rdquo; durchführen.&lt;/p>
&lt;h5 id="nachladen-des-mottos-1">Nachladen des Mottos&lt;/h5>
&lt;p>Zum Nachladen des Mottos der Bundesländer gehen wir im &amp;ldquo;Bundesländer&amp;rdquo;-Projekt diesmal über das Spaltenmenü
&amp;ldquo;&lt;strong>Bundesland&lt;/strong>&amp;ldquo;
&lt;i class="far fa-caret-square-down pr-1 fa-fw">&lt;/i>&amp;quot;Edit column&amp;quot;
&lt;i class="fas fa-caret-right pr-1 fa-fw">&lt;/i>&amp;quot;Add column based on this column&amp;hellip;&amp;rdquo;
und verwenden den folgenden GREL Ausdruck.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="nx">cell&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">cross&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;Bundesländer Motto&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;Bundesland&amp;#34;&lt;/span>&lt;span class="p">).&lt;/span>&lt;span class="nx">cells&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s2">&amp;#34;Mottotext&amp;#34;&lt;/span>&lt;span class="p">].&lt;/span>&lt;span class="nx">value&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="mi">0&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Wie in Abbildung 9 zu sehen ist, hat der Abgleich zwischen diesen beiden Projekten kein Problem, da die Bundesländer hier einheitlich geschrieben sind.&lt;/p>
&lt;figure id="figure-bildschirmfoto-des-spalten-hinzufügen-dialogs-mit-cross-für-den-mottotext-in-openrefine">
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="Bildschirmfoto des Spalten hinzufügen Dialogs mit cross() für den Mottotext in OpenRefine." srcset="
/post/2021-12-gemeinsam-an-openrefine-projekten-arbeiten/screenshot-openrefine-dialog-cross-motto-2_hu6697b78a45b788c719d01c8a114442f9_24083_d0669a6f0087e5eea3f45d6c37792cd2.webp 400w,
/post/2021-12-gemeinsam-an-openrefine-projekten-arbeiten/screenshot-openrefine-dialog-cross-motto-2_hu6697b78a45b788c719d01c8a114442f9_24083_5f781075b76ac04fe415c7507939cead.webp 760w,
/post/2021-12-gemeinsam-an-openrefine-projekten-arbeiten/screenshot-openrefine-dialog-cross-motto-2_hu6697b78a45b788c719d01c8a114442f9_24083_1200x1200_fit_q75_h2_lanczos_3.webp 1200w"
src="https://fdmlab.landesarchiv-bw.de/post/2021-12-gemeinsam-an-openrefine-projekten-arbeiten/screenshot-openrefine-dialog-cross-motto-2_hu6697b78a45b788c719d01c8a114442f9_24083_d0669a6f0087e5eea3f45d6c37792cd2.webp"
width="760"
height="505"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;figcaption data-pre="Abbildung&amp;nbsp;" data-post=":&amp;nbsp;" class="numbered">
Bildschirmfoto des Spalten hinzufügen Dialogs mit cross() für den Mottotext in OpenRefine.
&lt;/figcaption>&lt;/figure>
&lt;h5 id="nachladen-der-hauptstadt-1">Nachladen der Hauptstadt&lt;/h5>
&lt;p>Zum Nachladen der Hauptstädte der Bundesländer gehen wir im &amp;ldquo;Bundesländer&amp;rdquo;-Projekt diesmal über das Spaltenmenü
&amp;ldquo;&lt;strong>Bundesland&lt;/strong>&amp;ldquo;
&lt;i class="far fa-caret-square-down pr-1 fa-fw">&lt;/i>&amp;quot;Edit column&amp;quot;
&lt;i class="fas fa-caret-right pr-1 fa-fw">&lt;/i>&amp;quot;Add column based on this column&amp;hellip;&amp;rdquo;
und verwenden den folgenden GREL Ausdruck.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="nx">cell&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">cross&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;Bundesländer Hauptstadt&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;Bundesland&amp;#34;&lt;/span>&lt;span class="p">).&lt;/span>&lt;span class="nx">cells&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s2">&amp;#34;Hauptstadt&amp;#34;&lt;/span>&lt;span class="p">].&lt;/span>&lt;span class="nx">value&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="mi">0&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Wie in Abbildung 10 zu sehen ist, hat der Abgleich hier Probleme, da die Bundesländer teilweise unterschiedlich geschrieben sind.
Es fehlen Ergänzungen wie &amp;ldquo;Freistaat&amp;rdquo;. Daher können die Daten für diese Bundesländer nicht nachgeladen werden.&lt;/p>
&lt;figure id="figure-bildschirmfoto-des-spalten-hinzufügen-dialogs-mit-cross-für-die-hauptstadt-in-openrefine">
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="Bildschirmfoto des Spalten hinzufügen Dialogs mit cross() für die Hauptstadt in OpenRefine." srcset="
/post/2021-12-gemeinsam-an-openrefine-projekten-arbeiten/screenshot-openrefine-dialog-cross-hauptstadt-2_hu4c75d7fba194ae1d4237304cd6172606_24268_a132f64f5f87419fa9c7732f38156bd3.webp 400w,
/post/2021-12-gemeinsam-an-openrefine-projekten-arbeiten/screenshot-openrefine-dialog-cross-hauptstadt-2_hu4c75d7fba194ae1d4237304cd6172606_24268_f7b3d12e0daab7746eb26507b37ab9d0.webp 760w,
/post/2021-12-gemeinsam-an-openrefine-projekten-arbeiten/screenshot-openrefine-dialog-cross-hauptstadt-2_hu4c75d7fba194ae1d4237304cd6172606_24268_1200x1200_fit_q75_h2_lanczos_3.webp 1200w"
src="https://fdmlab.landesarchiv-bw.de/post/2021-12-gemeinsam-an-openrefine-projekten-arbeiten/screenshot-openrefine-dialog-cross-hauptstadt-2_hu4c75d7fba194ae1d4237304cd6172606_24268_a132f64f5f87419fa9c7732f38156bd3.webp"
width="760"
height="473"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;figcaption data-pre="Abbildung&amp;nbsp;" data-post=":&amp;nbsp;" class="numbered">
Bildschirmfoto des Spalten hinzufügen Dialogs mit cross() für die Hauptstadt in OpenRefine.
&lt;/figcaption>&lt;/figure>
&lt;h4 id="ergebnis">Ergebnis&lt;/h4>
&lt;figure id="figure-bildschirmfoto-von-openrefine-mit-den-bundesländern-und-den-zusätzlichen-spalten-aus-anderen-projekten">
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="Bildschirmfoto von OpenRefine mit den Bundesländern und den zusätzlichen Spalten aus anderen Projekten." srcset="
/post/2021-12-gemeinsam-an-openrefine-projekten-arbeiten/screenshot-openrefine-bundeslaender-2_hu80e7646e9d78f4fe605d75de5ca9f324_25607_e877a2011489f5239b704e1e440398a0.webp 400w,
/post/2021-12-gemeinsam-an-openrefine-projekten-arbeiten/screenshot-openrefine-bundeslaender-2_hu80e7646e9d78f4fe605d75de5ca9f324_25607_4d9aabd79641cebb0a830ebcd68f03dc.webp 760w,
/post/2021-12-gemeinsam-an-openrefine-projekten-arbeiten/screenshot-openrefine-bundeslaender-2_hu80e7646e9d78f4fe605d75de5ca9f324_25607_1200x1200_fit_q75_h2_lanczos_3.webp 1200w"
src="https://fdmlab.landesarchiv-bw.de/post/2021-12-gemeinsam-an-openrefine-projekten-arbeiten/screenshot-openrefine-bundeslaender-2_hu80e7646e9d78f4fe605d75de5ca9f324_25607_e877a2011489f5239b704e1e440398a0.webp"
width="760"
height="363"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;figcaption data-pre="Abbildung&amp;nbsp;" data-post=":&amp;nbsp;" class="numbered">
Bildschirmfoto von OpenRefine mit den Bundesländern und den zusätzlichen Spalten aus anderen Projekten.
&lt;/figcaption>&lt;/figure>
&lt;p>Der Abgleich mit &lt;code>cross()&lt;/code> innerhalb von OpenRefine funktioniert recht einfach, solange es eine Spalte mit eindeutigen Werten gibt.
Der Abgleich stört sich auch nicht an Sonderzeichen, Leerzeichen oder fehlenden Werten.&lt;/p>
&lt;p>Problematisch wird es, wenn die Werte der Spalten, die abgeglichen werden, nicht komplett übereinstimmen.
Diese sind in Abbildung 11 farblich hervorgehoben. In solchen Fällen empfiehlt sich das im nächsten Abschnitt besprochene lokale Reconciling.&lt;/p>
&lt;h3 id="zusammenführen-mit-lokalem-reconciling">Zusammenführen mit lokalem Reconciling&lt;/h3>
&lt;p>Wir hatten in
&lt;a href="https://fdmlab.landesarchiv-bw.de/post/2021-09-fuenf-dinge-die-wir-an-openrefine-moegen/">Fünf Dinge, die wir an OpenRefine mögen&lt;/a>
schon die Architektur von OpenRefine gelobt, da diese so gestaltet ist, dass OpenRefine auch mit anderen APIs kommunizieren kann.
Besonders unterstützt ist dabei das &lt;a href="https://reconciliation-api.github.io/specs/latest/" target="_blank" rel="noopener">Reconciliation Service API Protokoll&lt;/a>. Damit können Daten in einem OpenRefine-Projekt nicht nur gegen &lt;a href="https://docs.openrefine.org/manual/wikibase/overview" target="_blank" rel="noopener">Wikidata&lt;/a> oder die &lt;a href="https://lobid.org/gnd/reconcile" target="_blank" rel="noopener">GND&lt;/a> abgeglichen werden, sondern mit Werkzeugen wie &lt;a href="https://github.com/gitonthescene/csv-reconcile" target="_blank" rel="noopener">csv-reconcile&lt;/a> auch mit lokalen CSV-Dateien.&lt;/p>
&lt;div class="mermaid">---
title: OpenRefine Setup
config:
look: handDrawn
theme: neutral
---
flowchart LR
subgraph server[fas:fa-server Server]
server_or[fas:fa-gem OpenRefine]
server_api[fas:fa-code Reconciliation Service API]
end
subgraph laptop[fas:fa-laptop Laptop]
browser[far:fa-window-maximize Browser]
laptop_or[fas:fa-gem OpenRefine]
laptop_api[fas:fa-code Reconciliation Service API]
end
browser -.-> laptop_or &amp; server_or
laptop_or -.-> laptop_api &amp; server_api
server_or -.-> server_api
&lt;/div>
&lt;p>Für die Verwendung von csv-reconcile benötigt man &lt;a href="https://www.python.org/downloads/" target="_blank" rel="noopener">Python&lt;/a> auf seinem System.
Ist Python vorhanden, dann kann csv-reconcile einfach via Shell (PowerShell, Git Bash, &amp;hellip;) installiert werden.
Wir erstellen dafür erst eine virtuelle Umgebung in unserem Arbeitsordner, um csv-reconcile ausschließlich dort zu installieren.&lt;/p>
&lt;p>Der Arbeitsordner ist der Ordner, in dem wir unsere CSV-Dateien liegen haben, mit denen wir hier arbeiten.&lt;/p>
&lt;p>Die virtuelle Umgebung für Python ermöglicht es uns, Python Bibliotheken nur für dieses Projekt zu installieren,
so dass sie nicht mit Bibliotheken oder Python Versionen in anderen Projekten in Konflikt kommen.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-powershell" data-lang="powershell">&lt;span class="line">&lt;span class="cl">&lt;span class="p">&amp;gt;&lt;/span> &lt;span class="n">python&lt;/span> &lt;span class="n">-m&lt;/span> &lt;span class="n">venv&lt;/span> &lt;span class="n">venv&lt;/span> &lt;span class="c"># virtuelle Umgebung erstellen&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">&amp;gt;&lt;/span> &lt;span class="p">.\&lt;/span>&lt;span class="n">venv&lt;/span>&lt;span class="p">\&lt;/span>&lt;span class="n">Scripts&lt;/span>&lt;span class="p">\&lt;/span>&lt;span class="n">activate&lt;/span> &lt;span class="c"># virtuelle Umgebung aktivieren (Windows!)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">(&lt;/span>&lt;span class="n">venv&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">&amp;gt;&lt;/span> &lt;span class="n">pip&lt;/span> &lt;span class="n">install&lt;/span> &lt;span class="nb">csv-reconcile&lt;/span> &lt;span class="c"># csv-reconcile in virtuelle Umgebung installieren&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Da csv-reconcile in Version 0.3.0 den Vorschaudienst optional anbietet und keine automatische Erkennung von Encoding und Trennzeichen in CSV-Dateien hat, erstellen wir in unserem Arbeitsordner zusätzlich eine Datei &lt;code>config.py&lt;/code> mit dem folgenden Inhalt.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="n">CSVKWARGS&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="p">{&lt;/span>&lt;span class="s1">&amp;#39;delimiter&amp;#39;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s1">&amp;#39;,&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s1">&amp;#39;quotechar&amp;#39;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s1">&amp;#39;&amp;#34;&amp;#39;&lt;/span>&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">CSVENCODING&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s1">&amp;#39;UTF-8&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">MANIFEST&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;preview&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;url&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;http://localhost:5000/preview/{{id}}&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;width&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="mi">400&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;height&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="mi">300&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Anschließend können wir mit aktivierter virtueller Umgebung in unserem Arbeitsordner den lokalen Reconciling Service für die &amp;ldquo;Bundesländer Motto&amp;rdquo; CSV-Datei initiieren und starten.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-powershell" data-lang="powershell">&lt;span class="line">&lt;span class="cl">&lt;span class="p">(&lt;/span>&lt;span class="n">venv&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">&amp;gt;&lt;/span> &lt;span class="nb">csv-reconcile&lt;/span> &lt;span class="n">init&lt;/span> &lt;span class="p">-&lt;/span>&lt;span class="n">-config&lt;/span> &lt;span class="n">config&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="py">py&lt;/span> &lt;span class="nb">bundeslaender-motto&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="py">csv&lt;/span> &lt;span class="n">ID&lt;/span> &lt;span class="n">Bundesland&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">(&lt;/span>&lt;span class="n">venv&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">&amp;gt;&lt;/span> &lt;span class="nb">csv-reconcile&lt;/span> &lt;span class="n">serve&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Wenn wir mit dieser Datei fertig sind, können wir den lokalen Reconciling Service für die &amp;ldquo;Bundesländer Hauptstadt&amp;rdquo; CSV-Datei initiieren und starten.&lt;/p>
&lt;p>Ob die virtuelle Umgebung aktiv ist, sieht man an der Ergänzung &lt;code>(venv)&lt;/code> in der Shell.
Ansonnsten lässt sie sich mit &lt;code>.\venv\Scripts\activate&lt;/code> wieder aktivieren.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-powershell" data-lang="powershell">&lt;span class="line">&lt;span class="cl">&lt;span class="p">(&lt;/span>&lt;span class="n">venv&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">&amp;gt;&lt;/span> &lt;span class="nb">csv-reconcile&lt;/span> &lt;span class="n">init&lt;/span> &lt;span class="p">-&lt;/span>&lt;span class="n">-config&lt;/span> &lt;span class="n">config&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="py">py&lt;/span> &lt;span class="nb">bundeslaender-hauptstadt&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="py">csv&lt;/span> &lt;span class="n">ID&lt;/span> &lt;span class="n">Bundesland&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">(&lt;/span>&lt;span class="n">venv&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">&amp;gt;&lt;/span> &lt;span class="nb">csv-reconcile&lt;/span> &lt;span class="n">serve&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
&lt;div class="alert alert-note">
&lt;div>
Wir könnten die beiden lokalen Reconciling Services auch parallel laufen lassen, indem wir sie in unterschiedliche Ordner schieben und wie unter
&lt;a href="https://github.com/gitonthescene/csv-reconcile#common-configuration" target="_blank" rel="noopener">csv-reconcile: Common configuration&lt;/a>
beschrieben über die Variable &lt;code>SERVER_NAME&lt;/code> in der &lt;code>config.py&lt;/code> jeweils einen anderen Port setzen.
&lt;/div>
&lt;/div>
&lt;p>In OpenRefine fügen wir den lokalen Reconciliation Service hinzu, indem wir in einem Projekt über ein beliebiges
&amp;ldquo;Spaltenmenü&amp;quot;
&lt;i class="far fa-caret-square-down pr-1 fa-fw">&lt;/i>&amp;quot;Reconcile&amp;quot;
&lt;i class="fas fa-caret-right pr-1 fa-fw">&lt;/i>&amp;quot;Start reconciling&amp;rdquo; aufrufen und dort via &amp;ldquo;Add Standard Service&amp;hellip;&amp;rdquo;
die Adresse &lt;code>http://localhost:5000/reconcile&lt;/code> eingeben.
Der Port 5000 muss entsprechend angepasst werden, wenn er in der &lt;code>config.py&lt;/code> geändert wurde.&lt;/p>
&lt;p>Siehe auch die &lt;a href="https://docs.openrefine.org/manual/reconciling#getting-started" target="_blank" rel="noopener">OpenRefine-Dokumentation zu Reconciling: Getting started&lt;/a>.&lt;/p>
&lt;h4 id="zusammenführen-via-id-1">Zusammenführen via ID&lt;/h4>
&lt;p>Idealerweise haben wir eine eindeutige ID-Spalte, um die Projekte miteinander abzugleichen.
Dann ist der lokale Reconciliation Service fast schon etwas zu mächtig,
und wird von uns eher eingesetzt, wenn wir es vermeiden wollen,
zu viele OpenRefine-Projekte zu jonglieren.&lt;/p>
&lt;h5 id="nachladen-des-mottos-2">Nachladen des Mottos&lt;/h5>
&lt;p>Wir haben den lokalen Reconciling Service für das &amp;ldquo;Bundesländer Motto&amp;rdquo;-Projekt, wie im oberen Abschnitt beschrieben, am laufen.&lt;/p>
&lt;p>Zum Nachladen des Mottos der Bundesländer gehen wir im &amp;ldquo;Bundesländer&amp;rdquo;-Projekt über das Spaltenmenü
&amp;ldquo;ID&amp;quot;
&lt;i class="far fa-caret-square-down pr-1 fa-fw">&lt;/i>&amp;quot;Reconcile&amp;quot;
&lt;i class="fas fa-caret-right pr-1 fa-fw">&lt;/i>&amp;quot;Use values as identifiers&amp;rdquo;
und wählen unseren CSV Reconciliation Service aus.&lt;/p>
&lt;p>Die IDs werden nun alle zu Links. Wie im Maus-Hover in Abbildung 12 sehen wir, dass nicht alle IDs aufgelöst werden, sondern manchmal eine &amp;ldquo;Nicht gefunden&amp;rdquo; Meldung angezeigt wird.
Zur Erinnerung: es gibt nicht für alle Bundesländer ein Motto in unseren Daten!&lt;/p>
&lt;figure id="figure-bildschirmfoto-des-maus-hover-not-found-in-openrefine">
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="Bildschirmfoto des Maus-Hover &amp;#39;Not Found&amp;#39; in OpenRefine." srcset="
/post/2021-12-gemeinsam-an-openrefine-projekten-arbeiten/screenshot-openrefine-csv-reconcile-motto-1_hu39c718e5b27e6e52ff7ac1c81fff5d86_15469_f8f093dccbd7b2a8850142009bb6489e.webp 400w,
/post/2021-12-gemeinsam-an-openrefine-projekten-arbeiten/screenshot-openrefine-csv-reconcile-motto-1_hu39c718e5b27e6e52ff7ac1c81fff5d86_15469_b3a651b1ac2fd52b17ddff702eb9bddc.webp 760w,
/post/2021-12-gemeinsam-an-openrefine-projekten-arbeiten/screenshot-openrefine-csv-reconcile-motto-1_hu39c718e5b27e6e52ff7ac1c81fff5d86_15469_1200x1200_fit_q75_h2_lanczos_3.webp 1200w"
src="https://fdmlab.landesarchiv-bw.de/post/2021-12-gemeinsam-an-openrefine-projekten-arbeiten/screenshot-openrefine-csv-reconcile-motto-1_hu39c718e5b27e6e52ff7ac1c81fff5d86_15469_f8f093dccbd7b2a8850142009bb6489e.webp"
width="454"
height="394"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;figcaption data-pre="Abbildung&amp;nbsp;" data-post=":&amp;nbsp;" class="numbered">
Bildschirmfoto des Maus-Hover &amp;lsquo;Not Found&amp;rsquo; in OpenRefine.
&lt;/figcaption>&lt;/figure>
&lt;p>Den Mottotext können wir über
&amp;ldquo;ID&amp;quot;
&lt;i class="far fa-caret-square-down pr-1 fa-fw">&lt;/i>&amp;quot;Edit column&amp;quot;
&lt;i class="fas fa-caret-right pr-1 fa-fw">&lt;/i>&amp;quot;Add columns from reconciled values&amp;hellip;&amp;rdquo;
nachladen.
Wie in Abbildung 13 zu sehen ist, kann der Dienst auch mit nicht auflösbaren IDs umgehen und ignoriert diese einfach.&lt;/p>
&lt;figure id="figure-bildschirmfoto-des-reconciliation-dialogs-mit-dem-mottotext-in-openrefine">
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="Bildschirmfoto des Reconciliation Dialogs mit dem Mottotext in OpenRefine." srcset="
/post/2021-12-gemeinsam-an-openrefine-projekten-arbeiten/screenshot-openrefine-csv-reconcile-motto-2_hu8fbb82745c3be04cdb0e0c8fcbb4f230_18678_dd0eb9816e0f13c6bc8e21f81c61c1aa.webp 400w,
/post/2021-12-gemeinsam-an-openrefine-projekten-arbeiten/screenshot-openrefine-csv-reconcile-motto-2_hu8fbb82745c3be04cdb0e0c8fcbb4f230_18678_129cf3167d621935f4e2c6611f91fbf3.webp 760w,
/post/2021-12-gemeinsam-an-openrefine-projekten-arbeiten/screenshot-openrefine-csv-reconcile-motto-2_hu8fbb82745c3be04cdb0e0c8fcbb4f230_18678_1200x1200_fit_q75_h2_lanczos_3.webp 1200w"
src="https://fdmlab.landesarchiv-bw.de/post/2021-12-gemeinsam-an-openrefine-projekten-arbeiten/screenshot-openrefine-csv-reconcile-motto-2_hu8fbb82745c3be04cdb0e0c8fcbb4f230_18678_dd0eb9816e0f13c6bc8e21f81c61c1aa.webp"
width="760"
height="561"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;figcaption data-pre="Abbildung&amp;nbsp;" data-post=":&amp;nbsp;" class="numbered">
Bildschirmfoto des Reconciliation Dialogs mit dem Mottotext in OpenRefine.
&lt;/figcaption>&lt;/figure>
&lt;h5 id="nachladen-der-hauptstadt-2">Nachladen der Hauptstadt&lt;/h5>
&lt;p>Wir haben den lokalen Reconciling Service für das &amp;ldquo;Bundesländer Hauptstadt&amp;rdquo;-Projekt, wie im oberen Abschnitt beschrieben, am laufen.&lt;/p>
&lt;p>Zum Nachladen der Hauptstädte der Bundesländer gehen wir wieder im &amp;ldquo;Bundesländer&amp;rdquo;-Projekt über das Spaltenmenü
&amp;ldquo;ID&amp;quot;
&lt;i class="far fa-caret-square-down pr-1 fa-fw">&lt;/i>&amp;quot;Reconcile&amp;quot;
&lt;i class="fas fa-caret-right pr-1 fa-fw">&lt;/i>&amp;quot;Use values as identifiers&amp;rdquo;
und wählen unseren CSV Reconciliation Service aus.&lt;/p>
&lt;p>Die IDs werden nun alle wieder zu Links. Bei diesem Abgleich können alle IDs aufgelöst werden und wir sehen wie in Abbildung 14 überall Maus-Hover mit den entsprechenden Werten des gematchten Eintrags in der CSV-Datei.&lt;/p>
&lt;figure id="figure-bildschirmfoto-des-maus-hover-mit-csv-werten-in-openrefine">
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="Bildschirmfoto des Maus-Hover mit CSV Werten in OpenRefine." srcset="
/post/2021-12-gemeinsam-an-openrefine-projekten-arbeiten/screenshot-openrefine-csv-reconcile-hauptstadt-1_hu179a3c97bcee3c78ae52c69b1b89ffc0_9947_4b3ea587ba4655d167225c20f6e3dbd5.webp 400w,
/post/2021-12-gemeinsam-an-openrefine-projekten-arbeiten/screenshot-openrefine-csv-reconcile-hauptstadt-1_hu179a3c97bcee3c78ae52c69b1b89ffc0_9947_2af901b6da235bf730c1790b1d781bc9.webp 760w,
/post/2021-12-gemeinsam-an-openrefine-projekten-arbeiten/screenshot-openrefine-csv-reconcile-hauptstadt-1_hu179a3c97bcee3c78ae52c69b1b89ffc0_9947_1200x1200_fit_q75_h2_lanczos_3.webp 1200w"
src="https://fdmlab.landesarchiv-bw.de/post/2021-12-gemeinsam-an-openrefine-projekten-arbeiten/screenshot-openrefine-csv-reconcile-hauptstadt-1_hu179a3c97bcee3c78ae52c69b1b89ffc0_9947_4b3ea587ba4655d167225c20f6e3dbd5.webp"
width="452"
height="360"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;figcaption data-pre="Abbildung&amp;nbsp;" data-post=":&amp;nbsp;" class="numbered">
Bildschirmfoto des Maus-Hover mit CSV Werten in OpenRefine.
&lt;/figcaption>&lt;/figure>
&lt;h4 id="zusammenführen-via-werte-1">Zusammenführen via Werte&lt;/h4>
&lt;p>Es ist nicht immer eine eindeutige ID-Spalte vorhanden.
In so einem Fall spielt der lokale Reconciliation Service seine Stärke aus,
da wir mit ihm auch &amp;ldquo;ungenaue&amp;rdquo; Werte finden und matchen können.&lt;/p>
&lt;h5 id="nachladen-des-mottos-3">Nachladen des Mottos&lt;/h5>
&lt;p>Wir haben den lokalen Reconciling Service für das &amp;ldquo;Bundesländer Motto&amp;rdquo;-Projekt, wie im oberen Abschnitt beschrieben, am laufen.&lt;/p>
&lt;p>Zum Nachladen der Mottos der Bundesländer über die Wertespalte gehen wir zu
&amp;ldquo;Bundesland&amp;quot;
&lt;i class="far fa-caret-square-down pr-1 fa-fw">&lt;/i>&amp;quot;Reconcile&amp;quot;
&lt;i class="fas fa-caret-right pr-1 fa-fw">&lt;/i>&amp;quot;Start reconciling&amp;rdquo;
und wählen den &amp;ldquo;CSV Reconciling Service&amp;rdquo; aus.&lt;/p>
&lt;p>Wie in Abbildung 15 markiert, ist das automatische Matching etwas zu großzügig, so dass Bundesländer gematcht werden, weil sie zum Beispiel beide den Begriff &amp;ldquo;Freistaat&amp;rdquo; im Namen haben. Das kann manuell und bei größeren Datenmengen mit der Unterstützung von Facets auf den Konfidenzwerten (Wert wie gut das Matching passt) nachgearbeitet werden.&lt;/p>
&lt;figure id="figure-bildschirmfoto-des-ergebnis-des-automatischen-reconciling-in-openrefine">
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="Bildschirmfoto des Ergebnis des automatischen Reconciling in OpenRefine." srcset="
/post/2021-12-gemeinsam-an-openrefine-projekten-arbeiten/screenshot-openrefine-csv-reconcile-motto-3_hufaaadccb8b483f740a96e0e3e4446f9e_40846_ad0dc4da1e4daaaf27e3c0cfe4bc5541.webp 400w,
/post/2021-12-gemeinsam-an-openrefine-projekten-arbeiten/screenshot-openrefine-csv-reconcile-motto-3_hufaaadccb8b483f740a96e0e3e4446f9e_40846_726a2272f08749e7f5c6207a6c9f6f34.webp 760w,
/post/2021-12-gemeinsam-an-openrefine-projekten-arbeiten/screenshot-openrefine-csv-reconcile-motto-3_hufaaadccb8b483f740a96e0e3e4446f9e_40846_1200x1200_fit_q75_h2_lanczos_3.webp 1200w"
src="https://fdmlab.landesarchiv-bw.de/post/2021-12-gemeinsam-an-openrefine-projekten-arbeiten/screenshot-openrefine-csv-reconcile-motto-3_hufaaadccb8b483f740a96e0e3e4446f9e_40846_ad0dc4da1e4daaaf27e3c0cfe4bc5541.webp"
width="527"
height="640"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;figcaption data-pre="Abbildung&amp;nbsp;" data-post=":&amp;nbsp;" class="numbered">
Bildschirmfoto des Ergebnis des automatischen Reconciling in OpenRefine.
&lt;/figcaption>&lt;/figure>
&lt;p>Den Mottotext können wir dann wieder über
&amp;ldquo;Bundesland&amp;quot;
&lt;i class="far fa-caret-square-down pr-1 fa-fw">&lt;/i>&amp;quot;Edit column&amp;quot;
&lt;i class="fas fa-caret-right pr-1 fa-fw">&lt;/i>&amp;quot;Add columns from reconciled values&amp;hellip;&amp;rdquo;
nachladen.
Wie in Abbildung 16 zu sehen ist, kann der Dienst auch in diesem Fall mit nicht auflösbaren IDs umgehen und ignoriert diese einfach.&lt;/p>
&lt;figure id="figure-bildschirmfoto-des-reconciliation-dialogs-mit-dem-mottotext-in-openrefine">
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="Bildschirmfoto des Reconciliation Dialogs mit dem Mottotext in OpenRefine." srcset="
/post/2021-12-gemeinsam-an-openrefine-projekten-arbeiten/screenshot-openrefine-csv-reconcile-motto-4_hua1c00797d48b58235eee6dfe3065f9bd_25066_bda04180895739bc24eb0236691f4c66.webp 400w,
/post/2021-12-gemeinsam-an-openrefine-projekten-arbeiten/screenshot-openrefine-csv-reconcile-motto-4_hua1c00797d48b58235eee6dfe3065f9bd_25066_b8e80e344cc0bd1f5426a6a31ce7ef3c.webp 760w,
/post/2021-12-gemeinsam-an-openrefine-projekten-arbeiten/screenshot-openrefine-csv-reconcile-motto-4_hua1c00797d48b58235eee6dfe3065f9bd_25066_1200x1200_fit_q75_h2_lanczos_3.webp 1200w"
src="https://fdmlab.landesarchiv-bw.de/post/2021-12-gemeinsam-an-openrefine-projekten-arbeiten/screenshot-openrefine-csv-reconcile-motto-4_hua1c00797d48b58235eee6dfe3065f9bd_25066_bda04180895739bc24eb0236691f4c66.webp"
width="760"
height="555"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;figcaption data-pre="Abbildung&amp;nbsp;" data-post=":&amp;nbsp;" class="numbered">
Bildschirmfoto des Reconciliation Dialogs mit dem Mottotext in OpenRefine.
&lt;/figcaption>&lt;/figure>
&lt;h5 id="nachladen-der-hauptstadt-3">Nachladen der Hauptstadt&lt;/h5>
&lt;p>Wir haben den lokalen Reconciling Service für das &amp;ldquo;Bundesländer Hauptstadt&amp;rdquo;-Projekt, wie im oberen Abschnitt beschrieben, am laufen.&lt;/p>
&lt;p>Zum Nachladen der Hauptstädte der Bundesländer über die Wertespalte gehen wir zu
&amp;ldquo;Bundesland&amp;quot;
&lt;i class="far fa-caret-square-down pr-1 fa-fw">&lt;/i>&amp;quot;Reconcile&amp;quot;
&lt;i class="fas fa-caret-right pr-1 fa-fw">&lt;/i>&amp;quot;Start reconciling&amp;rdquo;
und wählen den &amp;ldquo;CSV Reconciliation Service&amp;rdquo; aus.&lt;/p>
&lt;p>Da wir in diesem Datensatz passende Einträge für alle Bundesländer haben, funktioniert das Matching, wie in Abbildung 17 zu sehen ist, recht gut, obwohl die Bundesländer teilweise anders geschrieben sind.&lt;/p>
&lt;figure id="figure-bildschirmfoto-der-oberfläche-von-openrefine-mit-den-reconciliation-ergebnissen-für-die-bundesländer">
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="Bildschirmfoto der Oberfläche von OpenRefine mit den Reconciliation Ergebnissen für die Bundesländer." srcset="
/post/2021-12-gemeinsam-an-openrefine-projekten-arbeiten/screenshot-openrefine-csv-reconcile-hauptstadt-2_hu4c933afed31667bc96f7b0214c9301a9_28800_fc3c3332f7db8636609b779c541fe682.webp 400w,
/post/2021-12-gemeinsam-an-openrefine-projekten-arbeiten/screenshot-openrefine-csv-reconcile-hauptstadt-2_hu4c933afed31667bc96f7b0214c9301a9_28800_39b10a95abf5152d45e2c4c10f882a39.webp 760w,
/post/2021-12-gemeinsam-an-openrefine-projekten-arbeiten/screenshot-openrefine-csv-reconcile-hauptstadt-2_hu4c933afed31667bc96f7b0214c9301a9_28800_1200x1200_fit_q75_h2_lanczos_3.webp 1200w"
src="https://fdmlab.landesarchiv-bw.de/post/2021-12-gemeinsam-an-openrefine-projekten-arbeiten/screenshot-openrefine-csv-reconcile-hauptstadt-2_hu4c933afed31667bc96f7b0214c9301a9_28800_fc3c3332f7db8636609b779c541fe682.webp"
width="311"
height="608"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;figcaption data-pre="Abbildung&amp;nbsp;" data-post=":&amp;nbsp;" class="numbered">
Bildschirmfoto der Oberfläche von OpenRefine mit den Reconciliation Ergebnissen für die Bundesländer.
&lt;/figcaption>&lt;/figure>
&lt;h4 id="ergebnis-1">Ergebnis&lt;/h4>
&lt;p>Der Abgleich mit dem lokalen Reconciling Service hat initial einen höherne Aufwand,
da sowohl Python auf dem System als auch der CSV Reconciling Service in OpenRefine eingerichtet werden müssen.
Dann ist das Verfahren jedoch deutlich flexibler als das Zusammenführen mit &lt;code>cross()&lt;/code>,
da darüber sowohl ein exaktes ID Matching und Nachladen von Spalten durchgeführt werden kann,
als auch ein so genanntes Fuzzy-Matching, bei dem die Werte in den Spalten nicht exakt übereinstimmen.&lt;/p>
&lt;p>In Abbildung 18 sind nochmal alle nachgeladenen Spalten abgebildet, wobei&lt;/p>
&lt;ol>
&lt;li>via &lt;code>cross()&lt;/code> auf der ID-Spalte&lt;/li>
&lt;li>via &lt;code>cross()&lt;/code> auf der Werte-Spalte (Namen Bundesland)&lt;/li>
&lt;li>via lokalem Reconciling Service auf der ID-Spalte&lt;/li>
&lt;li>via lokalem Reconciling Service auf der Werte-Spalte (Namen Bundesland)&lt;/li>
&lt;/ol>
&lt;p>nachgeladen wurde.&lt;/p>
&lt;figure id="figure-bildschirmfoto-von-openrefine-mit-den-bundesländern-und-den-zusätzlichen-spalten-aus-anderen-projekten">
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="Bildschirmfoto von OpenRefine mit den Bundesländern und den zusätzlichen Spalten aus anderen Projekten." srcset="
/post/2021-12-gemeinsam-an-openrefine-projekten-arbeiten/screenshot-openrefine-bundeslaender-3_huc3da5552be0ef16b9ee88e54332fa22a_26618_194dc0b3625ba75ea1a731c7431780d2.webp 400w,
/post/2021-12-gemeinsam-an-openrefine-projekten-arbeiten/screenshot-openrefine-bundeslaender-3_huc3da5552be0ef16b9ee88e54332fa22a_26618_ed5d312a4e0a6be6d76c570357b24a80.webp 760w,
/post/2021-12-gemeinsam-an-openrefine-projekten-arbeiten/screenshot-openrefine-bundeslaender-3_huc3da5552be0ef16b9ee88e54332fa22a_26618_1200x1200_fit_q75_h2_lanczos_3.webp 1200w"
src="https://fdmlab.landesarchiv-bw.de/post/2021-12-gemeinsam-an-openrefine-projekten-arbeiten/screenshot-openrefine-bundeslaender-3_huc3da5552be0ef16b9ee88e54332fa22a_26618_194dc0b3625ba75ea1a731c7431780d2.webp"
width="760"
height="220"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;figcaption data-pre="Abbildung&amp;nbsp;" data-post=":&amp;nbsp;" class="numbered">
Bildschirmfoto von OpenRefine mit den Bundesländern und den zusätzlichen Spalten aus anderen Projekten.
&lt;/figcaption>&lt;/figure>
&lt;h2 id="ausblick-auf-weitere-methoden">Ausblick auf weitere Methoden&lt;/h2>
&lt;p>Für das Zusammenführen von Datensätzen mit OpenRefine gibt es noch weitere Möglichkeiten, die sich aktuell in der Planung und Entwicklung befinden.&lt;/p>
&lt;p>Zum einen gibt es &lt;a href="%28https://github.com/OpenRefine/OpenRefine/issues/2003%29">Überlegungen&lt;/a>
für Projekte in OpenRefine automatisch einen Reconciliation Service zu erstellen,
so dass analog zu &lt;code>cross()&lt;/code> direkt innerhalb von OpenRefine ein Reconciling gegen andere Projekte durchgeführt werden kann.
Also Reconciling innerhalb von OpenRefine ohne separaten lokalen Reconciling Service.&lt;/p>
&lt;p>Zum anderen gibt es mit &lt;a href="https://datasette.io/" target="_blank" rel="noopener">Datasette&lt;/a>
ein komplettes Ökosystem um &lt;a href="https://datasette.io/tools" target="_blank" rel="noopener">Daten in SQLite einzulesen&lt;/a>
und anschließend via &lt;a href="https://datasette.io/plugins" target="_blank" rel="noopener">unterschiedlicher APIs&lt;/a> zur Verfügung zu stellen.
Es wird gerade auch ein &lt;a href="https://github.com/drkane/datasette-reconcile" target="_blank" rel="noopener">Reconciliation Plugin für Datasette&lt;/a> entwickelt.&lt;/p>
&lt;p>Gibt es in Arbeitsgruppen Datensätze, die intern oder extern veröffentlicht und auch für Reconciliation genutzt werden sollen, dann lohnt sich ein Blick auf dieses Werkzeug.&lt;/p>
&lt;h2 id="fazit">Fazit&lt;/h2>
&lt;p>OpenRefine bietet mit seiner Architektur das Potential zukünftig kollaboratives Arbeiten zu ermöglichen.
Bis dahin können wir uns selbst helfen und mit wenig Extraaufwand Aufgaben aufteilen und die Ergebnisse wieder zusammenführen.
Mit der &lt;code>cross()&lt;/code> Funktion können wir direkt Daten aus anderen OpenRefine-Projekten über ID-Spalten übernehmen.
Mit einem lokalem Reconciling Service können wir auch Daten aus unterschiedlichen Projekten verbinden.&lt;/p>
&lt;p>Bisher klappt das beschriebene Vorgehen im FDMLab ganz gut und wir beobachten weiterhin gespannt die Entwicklung sowohl von OpenRefine,
als auch von anderen Werkzeugen wie csv-reconcile und Datasette, die es hervorragend ergänzen.&lt;/p>
&lt;div class="footnotes" role="doc-endnotes">
&lt;hr>
&lt;ol>
&lt;li id="fn:1">
&lt;p>Die Mottotexte wurden aus &lt;a href="https://www.wikidata.org/" target="_blank" rel="noopener">Wikidata&lt;/a> geladen und sind daher genauso (un)vollständig, wie die Daten dort.&amp;#160;&lt;a href="#fnref:1" class="footnote-backref" role="doc-backlink">&amp;#x21a9;&amp;#xfe0e;&lt;/a>&lt;/p>
&lt;/li>
&lt;/ol>
&lt;/div></description></item><item><title>Erfahrungsbericht - Extraktion und Abgleich von Prokuratoren mit OpenRefine</title><link>https://fdmlab.landesarchiv-bw.de/post/2021-09-erfahrungsbericht-extraktion-und-abgleich-von-prokuratoren-mit-openrefine/</link><pubDate>Tue, 21 Sep 2021 00:00:00 +0000</pubDate><guid>https://fdmlab.landesarchiv-bw.de/post/2021-09-erfahrungsbericht-extraktion-und-abgleich-von-prokuratoren-mit-openrefine/</guid><description>&lt;p>In diesem Beitrag beschreiben wir unsere Erfahrungen bei der Textextraktion, der Deduplikation und dem Abgleich mit der GND von Indizes aus zehn Findbüchern.&lt;/p>
&lt;p>Wir haben bisher in Tutorials gezeigt, wie wir einen
&lt;a href="https://fdmlab.landesarchiv-bw.de/post/2021-07-findbuch-index-mit-openrefine-aufbereiten/">Findbuch Index mit OpenRefine aufbereiten&lt;/a>
und wie wir diese &lt;a href="https://fdmlab.landesarchiv-bw.de/post/2021-08-findbuch-daten-mit-openrefine-wiederverwenden/">Findbuch Daten mit OpenRefine wiederverwenden&lt;/a> können.&lt;/p>
&lt;p>Die dabei gesammelten Erfahrungen haben wir anschließend praktisch angewendet und
die Indizes der Prokuratoren aus den Findbüchern zu den Akten des Reichskammergerichts
in den Staatsarchiven Wertheim und Sigmaringen, sowie die Bände 1 - 8 im Hauptstaatsarchiv Stuttgart mit OpenRefine aufgearbeitet und mit der GND abgeglichen.&lt;/p>
&lt;h2 id="generelle-daten">Generelle Daten&lt;/h2>
&lt;p>&lt;strong>Text&lt;/strong>:&lt;/p>
&lt;ul>
&lt;li>10 Bände&lt;/li>
&lt;li>10.339 Textzeilen&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>CSV&lt;/strong>:&lt;/p>
&lt;ul>
&lt;li>2.912 Indexeinträge&lt;/li>
&lt;li>Davon 100 Aliase&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>Deduplikation&lt;/strong>:&lt;/p>
&lt;ul>
&lt;li>472 Prokuratoren&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>Abgleich mit GND&lt;/strong>:&lt;/p>
&lt;ul>
&lt;li>275 ohne GND Eintrag&lt;/li>
&lt;li>197 mit GND Eintrag (ca. 42 Prozent)&lt;/li>
&lt;/ul>
&lt;h2 id="anwenden-mehrerer-teilschritte">Anwenden mehrerer Teilschritte&lt;/h2>
&lt;div class="mermaid">---
title: Extraktionsprozess
config:
look: handDrawn
theme: neutral
---
flowchart LR
subgraph books[fas:fa-book Bände]
band1[Band 46/1.txt]
bandn[Band 46/...]
band8[Band 46/8.txt]
band9[Band 46/57.txt]
band10[Band 57/Wertheim.txt]
end
subgraph csvs[fas:fa-file-csv CSV]
csv1[CSV Band 46/1.csv]
csvn[CSV Band 46/...]
csv8[CSV Band 46/8.csv]
csv9[CSV Band 57.csv]
csv10[CSV Band 57/Wertheim.csv]
end
db[fas:fa-file-csv Prokuratoren.csv]
gnd[fas:fa-database GND]
result[fas:fa-project-diagram Prokuratoren]
band1 --fas:fa-gem--> csv1 --fas:fa-magic--> db
bandn --fas:fa-gem--> csvn --fas:fa-magic--> db
band8 --fas:fa-gem--> csv8 --fas:fa-magic--> db
band9 --fas:fa-gem--> csv9 --fas:fa-magic--> db
band10 --fas:fa-gem--> csv10 --fas:fa-magic--> db
db &amp; gnd --fas:fa-gem--> result
&lt;/div>
&lt;p>Wir haben uns dazu entschieden, aus jeder Findbuch(text)datei mit OpenRefine eine CSV Datei mit den Informationen zu den Prokuratoren zu extrahieren und die zehn CSV Dateien anschließend zusammenzufassen.&lt;/p>
&lt;div class="mermaid">---
title: Extraktionsprozess
config:
look: handDrawn
theme: neutral
---
flowchart LR
subgraph books[fas:fa-book Bände]
band1[Band 46/1.txt]
bandn[Band 46/...]
band8[Band 46/8.txt]
band9[Band 46/57.txt]
band10[Band 57/Wertheim.txt]
end
txt[fas:fa-file-txt Bände.txt]
db[fas:fa-file-csv Prokuratoren.csv]
gnd[fas:fa-database GND]
result[fas:fa-project-diagram Prokuratoren]
band1 &amp; bandn &amp; band9 &amp; band10 --fas:fa-magic--> txt --fas:fa-gem--> db
db &amp; gnd --fas:fa-gem--> result
&lt;/div>
&lt;p>Es wäre auch denkbar gewesen, die zehn Textdateien in einer Textdatei zusammenzufassen und daraus mit OpenRefine in einem Projekt eine CSV Datei zu erstellen.
Das Layout der einzelnen Findbücher unterschied sich jedoch so, dass wir uns anders entschieden.
Im Nachhinein wäre die Lösung mit einer Textdatei als Grundlage einfacher zu handhaben gewesen,
da wir bei unserem Vorgehen systematische Fehler in allen zehn Projekten nachzukorrigieren hatten.&lt;/p>
&lt;p>Um die einzelnen Operationen zwischen den Projekten besser austauschen zu können, haben wir die groben Schritte, wie zum Beispiel &amp;ldquo;zweispaltiges Layout in einspaltiges Layout umwandeln&amp;rdquo;, als Sammlung von mehreren Operationen in separaten &lt;code>.json&lt;/code> Dateien vorgehalten. Diese haben wir dann über die &amp;ldquo;History&amp;rdquo; Funktion von OpenRefine auf das aktuelle Projekt angewendet.
Darüber haben wir auch schon in &lt;a href="https://fdmlab.landesarchiv-bw.de/post/2021-08-findbuch-daten-mit-openrefine-wiederverwenden/">Findbuch Daten mit OpenRefine wiederverwenden&lt;/a> geschrieben.&lt;/p>
&lt;p>So konnten wir iterativ mehrere Operationen gleichzeitig anwenden, das Ergebnis überprüfen
und bei Bedarf die Operationen wieder rückgängig machen, sie anpassen und neu anwenden.
Hierbei wäre es praktisch gewesen, wenn man sich einzelne Versionen in der History von OpenRefine hätte markieren können, um einfacher dorthin zurückspringen zu können.&lt;/p>
&lt;p>Nachdem wir die CSV Dateien zusammengefasst hatten und in einem neuen Projekt die Deduplikation mit OpenRefine begannen, stellten wir fest,
dass es trotz sorgfältiger manueller Prüfung nach wie vor Extraktionsfehler in den Einzelprojekten gab.&lt;/p>
&lt;p>Daher geben wir hier als Tipp weiter, die Projekte und Zwischenschritte automatisch zu validieren.
Dafür kann zum Beispiel in OpenRefine mit Textfiltern und regulären Ausdrücken überprüft werden,
ob es noch Zahlen oder andere unerwartete Zeichen in den Namen gibt, die Jahreszahlen und Verweise richtig formatiert sind, &amp;hellip;&lt;/p>
&lt;h2 id="deduplikation-mit-clusterverfahren">Deduplikation mit Clusterverfahren&lt;/h2>
&lt;p>Zur Deduplikation verwendeten wir die in &lt;a href="https://docs.openrefine.org/manual/cellediting#cluster-and-edit" target="_blank" rel="noopener">OpenRefine integrierten Cluster Verfahren&lt;/a>.
Da wir unterschiedliche Arten von Duplizierungen hatten, verwendeten wir mehrere der angebotenen Verfahren nacheinander, bis wir keine Cluster mehr automatisiert finden konnten.&lt;/p>
&lt;p>Probleme machten hierbei alternative Schreibweisen, die in unseren Findbüchern durch Klammerung kompakt zusammengefasst wurden.
Beispielsweise gab es für &lt;a href="http://d-nb.info/gnd/1019755717" target="_blank" rel="noopener">Re(c)hlinger, Johann&lt;/a>
in den Findbüchern auch die Schreibweise &lt;em>Rehlinger, Johann&lt;/em> und &lt;em>Re&lt;strong>c&lt;/strong>hlinger Johann&lt;/em>.&lt;/p>
&lt;p>Dies konnte durch die Clusterverfahren gut erkannt und zusammengeführt werden.&lt;/p>
&lt;p>Schwieriger wurde es bei der automatischen Zusammenführung von &lt;a href="http://d-nb.info/gnd/104263172" target="_blank" rel="noopener">Brandt, (Johann) Ferdinand Wilhelm von&lt;/a>,
mit &lt;em>Brandt, Ferdinand Wilhelm&lt;/em>, da hier der geklammerte Ausdruck relativ zum Namen recht lang ist.&lt;/p>
&lt;p>Wenn der Anteil des geklammerten Namens zu groß wird, dann finden die verfügbaren automatischen Clustermethoden keine (sinnvolle) Ähnlichkeit mehr.
Dies war beispielsweise bei &lt;a href="http://d-nb.info/gnd/1161753699" target="_blank" rel="noopener">Müller (Mulher), Christoph&lt;/a> und &lt;em>Müller, Christoph&lt;/em> der Fall.&lt;/p>
&lt;h2 id="abgleich-mit-der-gnd">Abgleich mit der GND&lt;/h2>
&lt;p>Der Abgleich der Daten mit der &lt;a href="https://lobid.org/gnd/reconcile" target="_blank" rel="noopener">GND via lobid&lt;/a> nahm die meiste Zeit in Anspruch.
Um die Sortierung der Suchtreffer zu verbessern, haben wir eine zusätzliche Spalte &amp;ldquo;Beruf&amp;rdquo; mit dem Wert &amp;ldquo;Jurist&amp;rdquo; eingefügt und mit der Eigenschaft &lt;a href="https://d-nb.info/standards/elementset/gnd#professionOrOccupation" target="_blank" rel="noopener">professionOrOccupation&lt;/a> abgeglichen.&lt;/p>
&lt;p>Probleme gab es mit den schon erwähnten Namen mit Alternativen in Klammern,
da &lt;a href="https://github.com/hbz/lobid-gnd/issues/287" target="_blank" rel="noopener">geklammerte Ausdrücke Probleme bei der Verarbeitung durch die lobid API&lt;/a> haben.&lt;/p>
&lt;p>Ein wesentlicher Aufwandsfaktor war die fehlende Möglichkeit zur Einschränkung der Lebens- und Wirkungsdaten.
Hier hatte lobid schon auf unseren letzten Blogpost reagiert und das Feature im März 2022 umgesetzt. &lt;sup id="fnref:1">&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref">1&lt;/a>&lt;/sup>&lt;/p>
&lt;h2 id="fazit">Fazit&lt;/h2>
&lt;p>Die Umwandlung der 10.339 Textzeilen zu 472 Prokuratoren ließ sich mit OpenRefine relativ problemlos bewältigen.
Durch den Abgleich der Prokuratoren über mehrere Findbücher konnten einige OCR-Fehler korrigiert oder alternative Schreibweisen aufgelöst werden.
Die anschließende Zuordnung zu GND-Nummern war hingegen langwierig.&lt;/p>
&lt;p>Mit 472 Juristen, die alle aus der gleichen Berufsgruppe kommen und auch an anderen Orten schriftliche Spuren (Doktorarbeiten, &amp;hellip;) hinterlassen haben,
war dieser Datensatz vergleichsweise einfach aufzuarbeiten.&lt;/p>
&lt;p>In den Findbüchern zu den Akten des Reichskammergerichts gibt es noch einen gemischten Orts- und Personenindex.
Dieser ist etwa 50mal so groß, wie der Index der Prokuratoren,
enthält unterschiedlichste Typen von Einträgen (Adel, Berufe, Familien, Orte, &amp;hellip;),
und enthält vermutlich deutlich weniger Treffer in der GND. &lt;sup id="fnref:2">&lt;a href="#fn:2" class="footnote-ref" role="doc-noteref">2&lt;/a>&lt;/sup>&lt;/p>
&lt;p>Hier werden wir gegebenenfalls zusätzliche externe Werkzeuge bemühen,
wie wir es für den Artikel &lt;a href="https://fdmlab.landesarchiv-bw.de/post/2021-08-ner-mit-openrefine-und-spacy/">Named Entity Recognition mit OpenRefine und spaCy&lt;/a>
getestet haben.&lt;/p>
&lt;div class="footnotes" role="doc-endnotes">
&lt;hr>
&lt;ol>
&lt;li id="fn:1">
&lt;p>&lt;strong>Update April 2022&lt;/strong>: Durch ein Update in dem lobid GND API für OpenRefine kann nun eine zeitliche Einschränkung beim Reconciliation vorgenommen werden. Details dazu finden sich unter &lt;a href="https://github.com/hbz/lobid-gnd/issues/304" target="_blank" rel="noopener">Using range query parameter via OpenRefine Reconciliation&lt;/a> auf GitHub und unter &lt;a href="https://fdmlab.landesarchiv-bw.de/workshop/openrefine-fortgeschrittene/15-erweiterter-gnd-abgleich-mit-lobid/">Erweiterter GND Abgleich mit lobid&lt;/a> auf unserem Blog.&amp;#160;&lt;a href="#fnref:1" class="footnote-backref" role="doc-backlink">&amp;#x21a9;&amp;#xfe0e;&lt;/a>&lt;/p>
&lt;/li>
&lt;li id="fn:2">
&lt;p>Es kostet mehr Aufwand zu überprüfen, wenn etwas nicht da ist, als wenn es sofort ein eindeutiges Ergebnis gibt.&amp;#160;&lt;a href="#fnref:2" class="footnote-backref" role="doc-backlink">&amp;#x21a9;&amp;#xfe0e;&lt;/a>&lt;/p>
&lt;/li>
&lt;/ol>
&lt;/div></description></item><item><title>Findbuchdaten mit OpenRefine wiederverwenden</title><link>https://fdmlab.landesarchiv-bw.de/post/2021-08-findbuch-daten-mit-openrefine-wiederverwenden/</link><pubDate>Tue, 24 Aug 2021 00:00:00 +0000</pubDate><guid>https://fdmlab.landesarchiv-bw.de/post/2021-08-findbuch-daten-mit-openrefine-wiederverwenden/</guid><description>&lt;p>In diesem Artikel behandeln wir die Frage, wie wir schon aufbereitete Daten mit OpenRefine wiederverwenden können.&lt;/p>
&lt;p>Wir haben schon einen &lt;a href="https://fdmlab.landesarchiv-bw.de/post/2021-07-findbuch-index-mit-openrefine-aufbereiten/">Findbuch Index mit OpenRefine aufbereitet&lt;/a>.
wenn wir nun den Prokuratoren Index von &amp;ldquo;&lt;em>Band 57: Akten des Reichskammergerichts im Staatsarchiv Sigmaringen - Inventar des Bestands R 7. Bearb. von Raimund J. Weber. Kohlhammer 2004&lt;/em>&amp;rdquo; bearbeiten wollen, dann wäre zu erwarten, dass wir das Projekt nachnutzen können.&lt;/p>
&lt;p>Dies ist bedingt möglich. Zum einen können wir die Operationen aus der letzten Findbuchaufbereitung wiederverwenden.
Zum anderen können wir die Prokuratoren mit den Prokuratoren aus dem letzten Projekt abgleichen.&lt;/p>
&lt;p>Um es vorweg zu nehmen: es hat sich gezeigt, dass wir nur einen Teil der Operationen und Prokuratoren übernehmen können.
Aber gerade bei den Operationen ist das eine ziemliche Zeitersparnis.&lt;/p>
&lt;blockquote>
&lt;p>💾 Wir benötigen drei Dateien (Rechtsklick und &amp;ldquo;Ziel speichern unter&amp;hellip;&amp;rdquo;):&lt;/p>
&lt;/blockquote>
&lt;a href="https://fdmlab.landesarchiv-bw.de/data/rkg-57/akten-rkg-band-57-prokuratoren.txt" target="_blank">
&lt;i class="fas fa-file-alt pr-1 fa-fw">&lt;/i>Index Prokuratoren Akten RKG Band 57&lt;/a>
&lt;blockquote>
&lt;/blockquote>
&lt;a href="https://fdmlab.landesarchiv-bw.de/data/rkg-57/akten-rkg-band-57-openrefine-prokuratoren.json" target="_blank">
&lt;i class="fas fa-file-archive pr-1 fa-fw">&lt;/i>Index Prokuratoren Akten RKG Band 57 als OpenRefine Arbeitsschritte&lt;/a>
&lt;blockquote>
&lt;/blockquote>
&lt;a href="https://fdmlab.landesarchiv-bw.de/data/rkg-57/akten-rkg-band-57-wertheim-prokuratoren.csv" target="_blank">
&lt;i class="fas fa-file-csv pr-1 fa-fw">&lt;/i>Prokuratoren Akten RKG Band 57 - Wertheim als CSV&lt;/a>
&lt;p>Wir möchten explizit dazu einladen diese Dateien zu nutzen, um die einzelnen Schritte in OpenRefine selbst auszuprobieren und damit zu experimentieren.&lt;/p>
&lt;h2 id="operationen-übertragen">Operationen übertragen&lt;/h2>
&lt;p>Mit OpenRefine ist es möglich, die durchgeführten Operationen eines Projektes zu exportieren und in einem anderen Projekt zu importieren.
Beschrieben ist das im &lt;a href="https://docs.openrefine.org/manual/running#reusing-operations" target="_blank" rel="noopener">OpenRefine Manual&lt;/a>.&lt;/p>
&lt;p>Zuerst erstellen wir das Projekt in OpenRefine mit der Datei &lt;code>akten-rkg-band-57-prokuratoren.txt&lt;/code> als Grundlage.
Die Einstellungen sind in Abbildung 1 gezeigt.&lt;/p>
&lt;figure id="figure-bildschirmfoto-der-ansicht-zum-erstellen-neuer-projekte-in-openrefine">
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="Bildschirmfoto der Ansicht zum Erstellen neuer Projekte in OpenRefine." srcset="
/post/2021-08-findbuch-daten-mit-openrefine-wiederverwenden/openrefine-create-project_huffa3598330b71b2bc1ce4a2c5104db49_82035_a379f7001843141103fbf5d108508dcc.webp 400w,
/post/2021-08-findbuch-daten-mit-openrefine-wiederverwenden/openrefine-create-project_huffa3598330b71b2bc1ce4a2c5104db49_82035_98558c818e5edd40a414a8f0f169fb3d.webp 760w,
/post/2021-08-findbuch-daten-mit-openrefine-wiederverwenden/openrefine-create-project_huffa3598330b71b2bc1ce4a2c5104db49_82035_1200x1200_fit_q75_h2_lanczos_3.webp 1200w"
src="https://fdmlab.landesarchiv-bw.de/post/2021-08-findbuch-daten-mit-openrefine-wiederverwenden/openrefine-create-project_huffa3598330b71b2bc1ce4a2c5104db49_82035_a379f7001843141103fbf5d108508dcc.webp"
width="760"
height="335"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;figcaption data-pre="Abbildung&amp;nbsp;" data-post=":&amp;nbsp;" class="numbered">
Bildschirmfoto der Ansicht zum Erstellen neuer Projekte in OpenRefine.
&lt;/figcaption>&lt;/figure>
&lt;p>Mit der Schaltfläche &amp;ldquo;Extract&amp;hellip;&amp;rdquo; bei &amp;ldquo;Undo/Redo&amp;rdquo; (siehe Abbildung 2) können wir die Operationen aus einem Projekt exportieren und mit der Schaltfläche &amp;ldquo;Apply..&amp;rdquo; anwenden.&lt;/p>
&lt;figure id="figure-bildschirmfoto-der-schaltfläche-zum-anwenden-von-exportieren-operationen-in-openrefine">
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="Bildschirmfoto der Schaltfläche zum Anwenden von exportieren Operationen in OpenRefine." srcset="
/post/2021-08-findbuch-daten-mit-openrefine-wiederverwenden/openrefine-apply-history_hu97e08a0ed45663f2db56bc6d326fe481_11384_b26bc7192540f6fb481f61bd203cc177.webp 400w,
/post/2021-08-findbuch-daten-mit-openrefine-wiederverwenden/openrefine-apply-history_hu97e08a0ed45663f2db56bc6d326fe481_11384_fb0e24d71b56a427a414088450873dde.webp 760w,
/post/2021-08-findbuch-daten-mit-openrefine-wiederverwenden/openrefine-apply-history_hu97e08a0ed45663f2db56bc6d326fe481_11384_1200x1200_fit_q75_h2_lanczos_3.webp 1200w"
src="https://fdmlab.landesarchiv-bw.de/post/2021-08-findbuch-daten-mit-openrefine-wiederverwenden/openrefine-apply-history_hu97e08a0ed45663f2db56bc6d326fe481_11384_b26bc7192540f6fb481f61bd203cc177.webp"
width="404"
height="124"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;figcaption data-pre="Abbildung&amp;nbsp;" data-post=":&amp;nbsp;" class="numbered">
Bildschirmfoto der Schaltfläche zum Anwenden von exportieren Operationen in OpenRefine.
&lt;/figcaption>&lt;/figure>
&lt;p>Nach Klicken der Schaltfläche &amp;ldquo;Apply..&amp;rdquo; können wir die exportierten Operationen aus &lt;code>akten-rkg-band-57-openrefine-prokuratoren.json&lt;/code> wie in Abbildung 3 gezeigt einfügen und mit &amp;ldquo;Perform Operations&amp;rdquo; die Operationen auf dem aktuellen Projekt anwenden.&lt;/p>
&lt;figure id="figure-dialog-zum-anwenden-von-exportieren-operationen-in-openrefine">
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="Dialog zum Anwenden von exportieren Operationen in OpenRefine." srcset="
/post/2021-08-findbuch-daten-mit-openrefine-wiederverwenden/openrefine-dialog-history_hufea20d8a60dc05561e0381ca4d811726_30143_4372b6b75c032c3ab06937c00f8f67e0.webp 400w,
/post/2021-08-findbuch-daten-mit-openrefine-wiederverwenden/openrefine-dialog-history_hufea20d8a60dc05561e0381ca4d811726_30143_8fa74f20ca26e887000648417dff0f7b.webp 760w,
/post/2021-08-findbuch-daten-mit-openrefine-wiederverwenden/openrefine-dialog-history_hufea20d8a60dc05561e0381ca4d811726_30143_1200x1200_fit_q75_h2_lanczos_3.webp 1200w"
src="https://fdmlab.landesarchiv-bw.de/post/2021-08-findbuch-daten-mit-openrefine-wiederverwenden/openrefine-dialog-history_hufea20d8a60dc05561e0381ca4d811726_30143_4372b6b75c032c3ab06937c00f8f67e0.webp"
width="760"
height="572"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;figcaption data-pre="Abbildung&amp;nbsp;" data-post=":&amp;nbsp;" class="numbered">
Dialog zum Anwenden von exportieren Operationen in OpenRefine.
&lt;/figcaption>&lt;/figure>
&lt;p>Bei unserem ersten Versuch haben wir festgestellt, dass die Operationen von unserem &lt;a href="https://fdmlab.landesarchiv-bw.de/post/2021-07-findbuch-index-mit-openrefine-aufbereiten/">letzten Artikel&lt;/a> nicht direkt auf diesen Index anwendbar sind.
Beim Anwenden von Operationen aus einem anderen Projekt sind einige Dinge zu beachten.&lt;/p>
&lt;ol>
&lt;li>Die &lt;code>.json&lt;/code> Datei sollte mit einem Quelltexteditor wie (unter Windows) der Editor App, &lt;a href="https://notepad-plus-plus.org/" target="_blank" rel="noopener">Notepad++&lt;/a> oder &lt;a href="https://code.visualstudio.com/" target="_blank" rel="noopener">Visual Studio Code&lt;/a> geöffnet (und bearbeitet) werden.&lt;/li>
&lt;li>Die Spaltennamen in den beiden Projekten müssen die gleichen Namen haben.&lt;/li>
&lt;li>Manuelle Editieroperationen und Filteroperationen werden nicht mit übertragen.&lt;/li>
&lt;/ol>
&lt;p>In unserem konkreten Fall gab es zusätzlich die folgenden Probleme&lt;/p>
&lt;ul>
&lt;li>Die Extraktion der Seitenzahlen funktioniert nicht, da die Kopfzeilen sich unterscheiden.&lt;/li>
&lt;li>Das zweispaltige Layout hat statt 4 einen Minimalabstand von 3 Leerzeichen.&lt;/li>
&lt;li>Es gibt Zeilenumbrüche bei dem Namen der Prokuratoren und bei den Verweisen.&lt;/li>
&lt;li>Die Anpassungen für das &amp;ldquo;reconciling&amp;rdquo; lassen sich nicht übertragen.&lt;/li>
&lt;/ul>
&lt;p>In der Datei &lt;code>akten-rkg-band-57-openrefine-prokuratoren.json&lt;/code> haben wir die Operationen entsprechend bereinigt und angepasst, so dass sie direkt angewendet werden können. In Abbildung 4 ist das Ergebnis der Anwendung zu sehen.&lt;/p>
&lt;figure id="figure-bildschirmfoto-der-daten-nach-der-anwendung-der-operationen-in-openrefine">
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="Bildschirmfoto der Daten nach der Anwendung der Operationen in OpenRefine." srcset="
/post/2021-08-findbuch-daten-mit-openrefine-wiederverwenden/openrefine-view-after-history_hub588ecfdf40463365e3d01a1e0691329_166566_6814b68d0eb6f679068063d0552ada2f.webp 400w,
/post/2021-08-findbuch-daten-mit-openrefine-wiederverwenden/openrefine-view-after-history_hub588ecfdf40463365e3d01a1e0691329_166566_3a263ad6ace05aa5eea1c05c25d690aa.webp 760w,
/post/2021-08-findbuch-daten-mit-openrefine-wiederverwenden/openrefine-view-after-history_hub588ecfdf40463365e3d01a1e0691329_166566_1200x1200_fit_q75_h2_lanczos_3.webp 1200w"
src="https://fdmlab.landesarchiv-bw.de/post/2021-08-findbuch-daten-mit-openrefine-wiederverwenden/openrefine-view-after-history_hub588ecfdf40463365e3d01a1e0691329_166566_6814b68d0eb6f679068063d0552ada2f.webp"
width="760"
height="369"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;figcaption data-pre="Abbildung&amp;nbsp;" data-post=":&amp;nbsp;" class="numbered">
Bildschirmfoto der Daten nach der Anwendung der Operationen in OpenRefine.
&lt;/figcaption>&lt;/figure>
&lt;p>Bei &amp;ldquo;Albrecht von Lauterbach&amp;rdquo; ist eine andere Formatierung verwendet worden, die wir manuell nachkorrigiert haben.
Dafür sind wir in der &amp;ldquo;History&amp;rdquo; der Operationen zurück zu Schritt 33 gegangen.
Dann haben wir die fehlerhaften Einträge manuell via &amp;ldquo;inline editing&amp;rdquo; korrigiert.
Anschließend haben wir die (ehemaligen) Operationen 34 und 35 erneut via &amp;ldquo;Apply&amp;hellip;&amp;rdquo; angewendet.
Die (ehemaligen) Operationen 34 und 35 haben wir hier direkt zum Kopieren in den Artikel eingefügt:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-json" data-lang="json">&lt;span class="line">&lt;span class="cl">&lt;span class="p">[&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;op&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;core/column-addition&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;engineConfig&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;facets&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">[],&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;mode&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;row-based&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;baseColumnName&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;Nachname&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;expression&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;join ([coalesce(cells[&amp;#39;Nachname&amp;#39;].value,&amp;#39;&amp;#39;),coalesce(cells[&amp;#39;Vorname&amp;#39;].value,&amp;#39;&amp;#39;)],&amp;#39;, &amp;#39;)&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;onError&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;keep-original&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;newColumnName&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;Name&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;columnInsertIndex&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;description&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;Create column Name at index 1 based on column Nachname using expression join ([coalesce(cells[&amp;#39;Nachname&amp;#39;].value,&amp;#39;&amp;#39;),coalesce(cells[&amp;#39;Vorname&amp;#39;].value,&amp;#39;&amp;#39;)],&amp;#39;, &amp;#39;)&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;op&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;core/column-move&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;columnName&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;Name&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;index&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;description&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;Move column Name to position 0&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="zwischenfazit">Zwischenfazit&lt;/h3>
&lt;p>Die Übertragung von Verkettungen von Operationen, wie zum Beispiel das Auflösen eines zweispaltigen Layouts, ist praktisch und spart dem versierten Benutzer einiges an Zeit. Durch die automatisch generierten Beschreibungstexte für die Operationen ist es jedoch nicht leicht, die entsprechenden Blöcke von Operationen auch zu identifizieren.&lt;/p>
&lt;h2 id="abgleich-mit-lokaler-csv-datei">Abgleich mit lokaler CSV Datei&lt;/h2>
&lt;p>Mit der Datei &lt;code>akten-rkg-band-57-wertheim-prokuratoren.csv&lt;/code> besitzen wir eine (kleine) lokale Datenbank mit bereits aufbereiteten Prokuratoren.
Diese können wir zum Abgleich mit unseren aufbereiteten Daten in OpenRefine verwenden.
Dafür gibt es Werkzeuge, die eine CSV Datei als &amp;ldquo;Reconciliation Service&amp;rdquo; zur Verfügung stellen.&lt;/p>
&lt;h3 id="abgleich-mit-reconcile-csv-clojure">Abgleich mit reconcile-csv (Clojure)&lt;/h3>
&lt;p>Das Projekt &lt;a href="http://okfnlabs.org/reconcile-csv/" target="_blank" rel="noopener">reconcile-csv&lt;/a> basiert auf &lt;a href="https://clojure.org/" target="_blank" rel="noopener">Clojure&lt;/a> und lässt sich daher direkt mit der gleichen Java Version ausführen, mit der wir auch OpenRefine verwenden.
Dafür erstellen wir im Ordner mit der &lt;code>openrefine.exe&lt;/code> einen Ordner &lt;code>services&lt;/code> und kopieren die heruntergeladene &lt;code>reconcile-csv-0.1.2.jar&lt;/code> hinein.&lt;/p>
&lt;p>In dem Ordner öffnen wir anschließend eine PowerShell und führen mit der Java Version von OpenRefine die &lt;code>.jar&lt;/code> Datei aus.
Das CSV Reconciliation Service benötigt drei Parameter:&lt;/p>
&lt;ol>
&lt;li>Der Pfad zu der CSV Datei.&lt;/li>
&lt;li>Der Name der Spalte mit der abgeglichen werden soll.&lt;/li>
&lt;li>Der Name der Spalte mit einem eindeutigen Wert (ID) für jede Zeile. &lt;sup id="fnref:1">&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref">1&lt;/a>&lt;/sup>&lt;/li>
&lt;/ol>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-powershell" data-lang="powershell">&lt;span class="line">&lt;span class="cl">&lt;span class="p">.\&lt;/span>&lt;span class="n">server&lt;/span>&lt;span class="p">\&lt;/span>&lt;span class="n">target&lt;/span>&lt;span class="p">\&lt;/span>&lt;span class="n">jre&lt;/span>&lt;span class="p">\&lt;/span>&lt;span class="n">bin&lt;/span>&lt;span class="p">\&lt;/span>&lt;span class="n">java&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="py">exe&lt;/span> &lt;span class="n">-jar&lt;/span> &lt;span class="p">.\&lt;/span>&lt;span class="n">services&lt;/span>&lt;span class="p">\&lt;/span>&lt;span class="nb">reconcile-csv&lt;/span>&lt;span class="p">-&lt;/span>&lt;span class="mf">0.1&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="py">2&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="py">jar&lt;/span> &lt;span class="p">.\&lt;/span>&lt;span class="n">data&lt;/span>&lt;span class="p">\&lt;/span>&lt;span class="nb">akten-rkg&lt;/span>&lt;span class="o">-band&lt;/span>&lt;span class="p">-&lt;/span>&lt;span class="mf">57&lt;/span>&lt;span class="n">-wertheim-prokuratoren&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="py">csv&lt;/span> &lt;span class="n">Name&lt;/span> &lt;span class="n">Nr&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Mit &amp;ldquo;Name&amp;quot;
&lt;i class="far fa-caret-square-down pr-1 fa-fw">&lt;/i>&amp;quot;Reconcile&amp;quot;
&lt;i class="fas fa-caret-right pr-1 fa-fw">&lt;/i>&amp;quot;Start reconciling&amp;rdquo; können wir auf der Spalte Name den &amp;ldquo;Reconciliation&amp;rdquo; Vorgang starten und dort die Adresse &lt;code>http://localhost:8000/reconcile&lt;/code> als &amp;ldquo;Reconciliation Service&amp;rdquo; hinzufügen.&lt;/p>
&lt;p>Wie in Abbildung 5 gezeigt, gibt es für die einzelnen Ergebnisvorschläge auch eine Vorschau Funktion, in der die Inhalte der Tabellenzeile zum besseren Abgleich angezeigt werden.&lt;/p>
&lt;figure id="figure-bildschirmfoto-vom-abgleich-mit-reconcile-csv-in-openrefine">
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="Bildschirmfoto vom Abgleich mit &amp;#39;reconcile-csv&amp;#39; in OpenRefine." srcset="
/post/2021-08-findbuch-daten-mit-openrefine-wiederverwenden/openrefine-reconcile-dialog_hu34d6fa633cf59b7f58586ffcb0989db1_81588_5dabc4222d5b07f8bd9ce3745efb82f9.webp 400w,
/post/2021-08-findbuch-daten-mit-openrefine-wiederverwenden/openrefine-reconcile-dialog_hu34d6fa633cf59b7f58586ffcb0989db1_81588_9bb9395b3167fcab6b0f8776402bed8c.webp 760w,
/post/2021-08-findbuch-daten-mit-openrefine-wiederverwenden/openrefine-reconcile-dialog_hu34d6fa633cf59b7f58586ffcb0989db1_81588_1200x1200_fit_q75_h2_lanczos_3.webp 1200w"
src="https://fdmlab.landesarchiv-bw.de/post/2021-08-findbuch-daten-mit-openrefine-wiederverwenden/openrefine-reconcile-dialog_hu34d6fa633cf59b7f58586ffcb0989db1_81588_5dabc4222d5b07f8bd9ce3745efb82f9.webp"
width="760"
height="334"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;figcaption data-pre="Abbildung&amp;nbsp;" data-post=":&amp;nbsp;" class="numbered">
Bildschirmfoto vom Abgleich mit &amp;lsquo;reconcile-csv&amp;rsquo; in OpenRefine.
&lt;/figcaption>&lt;/figure>
&lt;p>Wir konnten mit dem lokalen Abgleich 28 Prokuratoren aus unserer Liste finden.&lt;/p>
&lt;p>An dieser Stelle würden wir gerne weitere Daten aus der CSV Datei laden, wie es von dem von &lt;a href="https://docs.openrefine.org/manual/reconciling#fetching-more-data" target="_blank" rel="noopener">OpenRefine unterstützen Data Extension API&lt;/a> angeboten wird.
Leider wird diese Funktionalität in diesem Service nicht unterstützt.
Da das Projekt Stand August 2021 seit 2015 nicht mehr weiterentwickelt wurde, ist damit auch nicht zu rechnen.&lt;sup id="fnref:2">&lt;a href="#fn:2" class="footnote-ref" role="doc-noteref">2&lt;/a>&lt;/sup>&lt;/p>
&lt;h3 id="abgleich-mit-csv-reconcile-python">Abgleich mit csv-reconcile (Python)&lt;/h3>
&lt;p>Ein neueres Projekt zum Abgleich mit lokalen CSV Dateien ist &lt;a href="https://github.com/gitonthescene/csv-reconcile" target="_blank" rel="noopener">csv-reconcile&lt;/a>, welches auf &lt;a href="https://www.python.org/" target="_blank" rel="noopener">Python&lt;/a> basiert und sich aktiv in der Entwicklung befindet.&lt;/p>
&lt;p>Wie wir schon im Artikel &lt;a href="https://fdmlab.landesarchiv-bw.de/post/2021-08-ner-mit-openrefine-und-spacy/">Named Entity Recognition mit OpenRefine und spaCy&lt;/a> festgestellt haben, ist die Verwendung von Python Frameworks mit OpenRefine aufwendiger, da wir dafür zusätzlich eine aktuelle Python Installation benötigen.&lt;/p>
&lt;p>Haben wir lokal Python installiert, dann können wir mit PowerShell im gleichen &lt;code>services&lt;/code> Ordner wie im letzten Abschnitt
eine virtuelle Python Umgebung anlegen (1),
diese virtuelle Umgebung aktivieren (2),
das Paket &lt;code>csv-reconcile&lt;/code> mit pip installieren (3),
und den &amp;ldquo;CSV Reconciliation Service&amp;rdquo; starten (4).&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-powershell" data-lang="powershell">&lt;span class="line">&lt;span class="cl">&lt;span class="n">python&lt;/span> &lt;span class="n">-m&lt;/span> &lt;span class="n">venv&lt;/span> &lt;span class="n">venv&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">.\&lt;/span>&lt;span class="n">venv&lt;/span>&lt;span class="p">\&lt;/span>&lt;span class="n">Scripts&lt;/span>&lt;span class="p">\&lt;/span>&lt;span class="n">activate&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">pip&lt;/span> &lt;span class="n">install&lt;/span> &lt;span class="nb">csv-reconcile&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">csv-reconcile&lt;/span> &lt;span class="p">-&lt;/span>&lt;span class="n">-init-db&lt;/span> &lt;span class="p">-&lt;/span>&lt;span class="n">-config&lt;/span> &lt;span class="n">config&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="py">py&lt;/span> &lt;span class="p">..\&lt;/span>&lt;span class="n">data&lt;/span>&lt;span class="p">\&lt;/span>&lt;span class="nb">akten-rkg&lt;/span>&lt;span class="o">-band&lt;/span>&lt;span class="p">-&lt;/span>&lt;span class="mf">57&lt;/span>&lt;span class="n">-wertheim-prokuratoren&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="py">csv&lt;/span> &lt;span class="n">Nr&lt;/span> &lt;span class="n">Name&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Leider konnte unsere CSV Datei auf Grund ihres Formates und Kodierung nicht auf Anhieb richtig geladen werden, so dass wir zusätzlich eine Konfigurationsdatei &lt;code>config.py&lt;/code> mit dem folgenden Inhalt im Ordner &lt;code>services&lt;/code> hinterlegt haben.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="n">CSVKWARGS&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="p">{&lt;/span>&lt;span class="s1">&amp;#39;delimiter&amp;#39;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s1">&amp;#39;,&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s1">&amp;#39;quotechar&amp;#39;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s1">&amp;#39;&amp;#34;&amp;#39;&lt;/span>&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">CSVENCODING&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s1">&amp;#39;UTF-8&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Der &amp;ldquo;CSV Reconciliation Service&amp;rdquo; ist anschließend unter &lt;code>http://localhost:5000/reconcile&lt;/code> erreichbar.&lt;/p>
&lt;p>Das Python Projekt ist deutlich flexibler und ausführlicher zu konfigurieren, als das ältere Clojure Projekt.
Es unterstützt auch die &amp;ldquo;Data Extension API&amp;rdquo;, so dass wir nach dem Abgleich weitere Spalten aus der CSV Datei nachladen können.
&lt;del>Leider fehlt noch eine Vorschau, so dass kein visueller Abgleich zum Beispiel mit den Wirkdaten der Prokuratoren möglich ist.&lt;/del>
Ab &lt;a href="https://github.com/gitonthescene/csv-reconcile/releases/tag/v0.3.0" target="_blank" rel="noopener">Version 0.3.0&lt;/a> gibt es eine optionale Vorschau Funktion.&lt;/p>
&lt;h2 id="abgleich-mit-der-gnd">Abgleich mit der GND&lt;/h2>
&lt;p>Nachdem wir etwa 10 Prozent der Prokuratoren mit unseren lokalen Daten abgleichen konnten, können wir nun den Rest direkt mit der Gemeinsamen Normdatei (GND) abgleichen.
Darauf sind wir in &lt;a href="https://fdmlab.landesarchiv-bw.de/post/2021-07-findbuch-index-mit-openrefine-aufbereiten/">Findbuch Index mit OpenRefine aufbereiten&lt;/a> genauer eingegangen und werden das daher hier nicht weiter vertiefen.&lt;/p>
&lt;h2 id="fazit">Fazit&lt;/h2>
&lt;div class="mermaid">---
title: Prozess
config:
look: handDrawn
theme: neutral
---
flowchart LR
text[fas:fa-file-alt Text]
code[fas:fa-code Code]
index[fas:fa-file-csv Index]
data[fas:fa-table Table]
partially[fas:fa-tasks Parts]
gnd[fas:fa-database GND]
semantic[fas:fa-project-diagram Graph]
text --> data --> partially --> semantic
code --> data
index --> partially
gnd --> semantic
&lt;/div>
&lt;p>Die Möglichkeit &lt;code>json&lt;/code> Schnippsel mit Verkettungen von Operationen für komplexe Aufgaben zu importieren gefällt uns, und wir werden diese Methode gegebenenfalls öfter verwenden.&lt;/p>
&lt;p>Für den komfortablen Abgleich mit einer lokalen CSV Datei fehlte den beiden getesteten Bibliotheken noch Funktionalität.&lt;/p>
&lt;p>Das auf Clojure basierende reconcile-csv lässt sich ohne großen Mehraufwand verwenden und bietet eine hilfreiche Vorschau Funktion.
Ohne eine Unterstützung der &amp;ldquo;Data Extension API&amp;rdquo; ist es für unsere Anwendungsfälle aber nur beschränkt nutzbar.&lt;/p>
&lt;p>Das auf Python basierende csv-reconcile benötigt eine lokale Python Installation und bietet noch keine Vorschau Funktion, ohne die sich der Datenabgleich teilweise mühsam gestaltet.&lt;/p>
&lt;p>Die Möglichkeit eigene Datenbanken in Form von CSV Dateien zu nutzen, oder wie im Falle der Indizes zu den Akten des Reichskammergerichts schrittweise aufzubauen, ist jedoch vorhanden und hat das Potential von großer Arbeitserleichterung.&lt;/p>
&lt;div class="footnotes" role="doc-endnotes">
&lt;hr>
&lt;ol>
&lt;li id="fn:1">
&lt;p>Da wir bei der Bearbeitung des Prokuratoren Index der Akten in Wertheim nicht alle Prokuratoren mit einer GND-ID verknüpfen konnten,
haben wir den Daten eine Spalte Nr mit der &amp;ldquo;GREL expression&amp;rdquo; &lt;code>row.index + 1&lt;/code> hinzugefügt.&amp;#160;&lt;a href="#fnref:1" class="footnote-backref" role="doc-backlink">&amp;#x21a9;&amp;#xfe0e;&lt;/a>&lt;/p>
&lt;/li>
&lt;li id="fn:2">
&lt;p>Eine Möglichkeit das &amp;ldquo;Data Extension Problem&amp;rdquo; zu umgehen, ist aus den abgeglichenen Daten eine neue Spalte mit der &amp;ldquo;GREL expression&amp;rdquo; &lt;code>cell.recon.match.id&lt;/code> zu erzeugen und die beiden Dateien anschließend mit einem anderen Werkzeug zusammenzuführen. Eine weitere Möglichkeit besteht darin, die andere CSV Datei in OpenRefine als Projekt zu laden und den Abgleich mit der Funktion &lt;a href="https://docs.openrefine.org/manual/grelfunctions#crosscell-s-projectname-s-columnname" target="_blank" rel="noopener">cross&lt;/a> durchzuführen.&amp;#160;&lt;a href="#fnref:2" class="footnote-backref" role="doc-backlink">&amp;#x21a9;&amp;#xfe0e;&lt;/a>&lt;/p>
&lt;/li>
&lt;/ol>
&lt;/div></description></item></channel></rss>