Stefan Franke · Daniel Schiffner

Entwicklung interaktiver Softwareanwendungen

Sitzung 6 — Datenbanken mit SQLite

PH Weingarten

Übersicht

  • Einstieg: AI Tandem Lab — Debugging mit KI
  • Kurze Wiederholung: Python & Flask
  • Warum überhaupt eine Datenbank?
  • Welche DB? → SQLite · SQL in 4 Befehlen
  • Tabellen & Beziehungen
  • Vom Rätsel zum Klick-Adventure · Architektur
  • Aufgaben

Einstieg: AI Tandem Lab

Debugging mit KI — Günther (A) & Roberta (B) haben je vier kleine Probleme

Arbeitsphase
20 min

4 Probleme mit einem KI-Tool erarbeiten & kritisch prüfen

Tandemphase
10 min

Erkenntnisse gegenseitig erklären (A ↔ B)

Ihr braucht: ein KI-Tool (ChatGPT, Claude, …)

Ablauf

2. Warteraum

Gruppe A oder B?

3. Arbeitsphase

A: Günther · B: Roberta — Bugs mit KI lösen

4. Tandemphase

gegenseitig erklären

Timer läuft automatisch – im Blick behalten!

Jetzt beitreten!

franke-lab.de/ai-tandem-lab

Präsenz
EIS26_6_OnSite
eis
Zoom
EIS26_6_Zoom
eis

Name eingeben → passende Session wählen → Passwort eis

Auswertung — was war bei Günther & Roberta los?

Navigation / Seite fehltfalscher Datei-Pfad
Änderung erscheint nichtBrowser-Cache → Hard Reload
Flask läuft nicht / App totvenv nicht aktiviert · Terminal geschlossen
Pinnwand / Zähler leerDaten beim Neustart weg — ?
Das letzte Problem lösen wir heute: Wir brauchen einen dauerhaften Speicher — eine Datenbank.

Kurze Wiederholung: Python & Flask

Warm-up, bevor wir die Datenbank anschließen:

server

Laufcheck: läuft eure App unter /app/? Notfalls venv aktivieren & python3 app.py.

lokal

Kleine Änderung: Text/Route anpassen → committen → Sync.

lokal

Mini-Rätsel: eine Route mit einer Frage & Antwortprüfung — das erweitern wir gleich mit der DB.

Schritt für Schritt in der Übung u18.

Warum überhaupt eine Datenbank?

Bisher: Liste im Arbeitsspeicher

eintraege = []   # nur im RAM

Beim Neustart der App ist alles weg.

Mit Datenbank

Daten liegen dauerhaft auf der Festplatte. Neustart? Alles noch da. Strukturiert abfragbar, erweiterbar, von mehreren Stellen nutzbar.

Eine Datenbank ist ein strukturiertes, dauerhaftes Abbild der Daten eurer Anwendung.

Welche Datenbank? → SQLite

Server-DB (MySQL, PostgreSQL)eigener Server, Nutzer, Passwörter — für große Systeme
Datei-DB (SQLite)eine Datei, kein Server, in Python eingebaut
Wir nehmen SQLite: import sqlite3 ist schon da, die ganze Datenbank ist eine Datei (adventure.db) — ideal für eine App auf einem Server. Gleiche Abfragesprache (SQL) wie die Großen.

SQL = relational (Tabellen). Daneben gibt es NoSQL (z. B. Dokumente) — für uns hier ist SQL genau richtig.

SQL in vier Befehlen

CREATE TABLE raeume (            -- Tabelle anlegen
    id INTEGER PRIMARY KEY,
    name TEXT,
    beschreibung TEXT
);

INSERT INTO raeume (name, beschreibung)   -- Zeile einfügen
       VALUES ('Eingangshalle', 'Eine schwere Tür fällt hinter dir zu.');

SELECT * FROM raeume WHERE id = 1;        -- Daten abfragen

UPDATE raeume SET beschreibung = '...' WHERE id = 1;  -- ändern

CREATE anlegen · INSERT hinzufügen · SELECT lesen · UPDATE ändern

Tabellen & Beziehungen

Ein Adventure ist von Natur aus relational: Räume und ihre Ausgänge.

raeume

id (PK)namebeschreibung
1Eingangshalle
2Krypta

ausgaenge

von_raumrichtungnach_raum
1links2
1rechts3

Primärschlüssel (id) macht jede Zeile eindeutig. Fremdschlüssel (von_raum, nach_raum) verweisen auf raeume.id — so hängen die Tabellen zusammen.

Vom Rätsel zum Klick-Adventure

Jeder Raum zeigt seine Beschreibung; die Ausgänge werden zu Klick-Buttons. Ein Klick lädt den nächsten Raum aus der DB.

Gestaltung: modern & minimalistisch — dunkle Fläche, klare moderne Schrift, dezenter Akzent. Kein 3D, keine Spielereien. Eure eigenen Ideen & Farben ausdrücklich erwünscht.

Krypta

Kaltes Kerzenlicht flackert. Zwei Gänge führen ins Dunkel.

← links rechts →

Architektur

public_html/app/
├── app.py         # Flask: /  und  /raum/<id>
├── init_db.py     # Tabellen + Starträume (im Repo)
├── adventure.db   # entsteht auf dem Server (untracked)
└── venv/          # (untracked)
import sqlite3
@app.route("/raum/<int:id>")
def raum(id):
    db = sqlite3.connect("adventure.db")
    r = db.execute(
      "SELECT name, beschreibung "
      "FROM raeume WHERE id=?", (id,)
    ).fetchone()
    ...
„DB installieren“? Bei SQLite fast nichts: sqlite3 ist in Python eingebaut. Ihr legt adventure.db einmalig per init_db.py auf dem Server an. Reinschauen: VS-Code-Extension „SQLite“. Die .db ist untracked und bleibt bei Auto-Deploy erhalten (*.db in .gitignore nur als Sicherheitsnetz).

Workflow — wo entsteht was?

Dateien schreibt ihr lokal. Ausgeführt — und die Datenbank angelegt — wird auf dem Server.

lokal — VS Code

Neue / geänderte Dateien in app/:

  • init_db.py neu
  • app.py (+ sqlite3, Route /raum)
  • .gitignore (+ *.db, optional)

→ Stage · Commit · Sync

git.md-phw.de

Forgejo-Repository — euer Stand liegt zentral.

server — Auto-Deploy

Dateien kommen automatisch an. Dann einmalig im Terminal:

source venv/bin/activate
python3 init_db.py   # legt adventure.db an
python3 app.py       # App starten
adventure.db entsteht auf dem Server (durch init_db.py), ist dort untracked und bleibt bei Auto-Deploy erhalten (reset --hard lässt untrackte Dateien in Ruhe). Der Server pullt nur, pusht nie. *.db in .gitignore ist nur ein optionales Sicherheitsnetz.

Aufgaben

Für alle — Schritt für Schritt: u18

  1. init_db.py anlegen → auf dem Server ausführen (Tabellen + 3 Starträume)
  2. app.py um sqlite3 + Route /raum/<id> erweitern → durch die Räume klicken

Pflicht: einen eigenen Raum + Ausgang per INSERT ergänzen.

Für Schnellere: Spielstand speichern (UPDATE) oder ein Rätsel als Tür-Schloss einbauen.

Heute geschafft?

  • Debugging mit KI — die vier häufigen Stolpersteine
  • Verstanden, warum wir eine Datenbank brauchen
  • SQLite angebunden — erstes Klick-Adventure aus der DB

Nächstes Mal: Adventure ausbauen — mehr Räume, Rätsel, Spielstand.