update
This commit is contained in:
@@ -86,6 +86,7 @@ CREATE TABLE IF NOT EXISTS bausteine (
|
||||
nennungen INTEGER NOT NULL DEFAULT 1,
|
||||
status TEXT NOT NULL DEFAULT 'kandidat',
|
||||
quellen TEXT NOT NULL DEFAULT '[]',
|
||||
reader TEXT NOT NULL DEFAULT '[]',
|
||||
updated_at TEXT NOT NULL,
|
||||
PRIMARY KEY (topic, titel_norm)
|
||||
)
|
||||
@@ -266,6 +267,10 @@ async def init_db():
|
||||
await db.execute("ALTER TABLE subbausteine ADD COLUMN fakten TEXT NOT NULL DEFAULT ''") # DEFAULT '' nötig für NOT NULL beim ADD COLUMN
|
||||
except aiosqlite.OperationalError:
|
||||
pass
|
||||
try: # Migration: bausteine.reader (Reader-Set je Kandidat, JSON) — exakte Konsens-Zählung (≥2 Reader)
|
||||
await db.execute("ALTER TABLE bausteine ADD COLUMN reader TEXT NOT NULL DEFAULT '[]'")
|
||||
except aiosqlite.OperationalError:
|
||||
pass
|
||||
# Migration: alte vertiefungen-Tabelle → baustein_texte (Bestand = lange Form, art 'deepdive')
|
||||
cursor = await db.execute("SELECT name FROM sqlite_master WHERE type = 'table' AND name = 'vertiefungen'")
|
||||
if await cursor.fetchone():
|
||||
@@ -714,15 +719,31 @@ async def delete_baustein_daten(topic: str) -> None:
|
||||
|
||||
# --- Bausteine-Pipeline-Inhalt: Inventar / Subbausteine / Frage-Muster / Coverage / State / Quelle ---
|
||||
|
||||
async def upsert_baustein(topic: str, titel_norm: str, titel: str, beschreibung: str = "", quellen: list | None = None) -> None:
|
||||
"""Kandidat einfügen oder Nennungszähler erhöhen. Erst-Beschreibung bleibt erhalten."""
|
||||
async def upsert_baustein(topic: str, titel_norm: str, titel: str, beschreibung: str = "",
|
||||
quellen: list | None = None, reader: str | None = None) -> None:
|
||||
"""Kandidat einfügen oder Reader-Set vereinigen. Erst-Beschreibung bleibt erhalten.
|
||||
|
||||
`reader` = ID des Recherche-Readers (z.B. "a5-1"). Die Vereinigung läuft race-frei in
|
||||
EINEM Statement (json1), weil mehrere Reader-Coroutinen nebenläufig upserten — ein
|
||||
read-modify-write über `await` würde Mitglieder verlieren. `nennungen` bleibt synchron
|
||||
zu `len(reader)`. `reader=None` (z.B. aus `_set_inventar`) lässt das Set unverändert."""
|
||||
db = await get_db()
|
||||
rid = reader if isinstance(reader, str) and reader else None
|
||||
await db.execute(
|
||||
"""INSERT INTO bausteine (topic, titel_norm, titel, beschreibung, nennungen, status, quellen, updated_at)
|
||||
VALUES (?, ?, ?, ?, 1, 'kandidat', ?, ?)
|
||||
"""INSERT INTO bausteine (topic, titel_norm, titel, beschreibung, nennungen, status, quellen, reader, updated_at)
|
||||
VALUES (?, ?, ?, ?, 1, 'kandidat', ?, ?, ?)
|
||||
ON CONFLICT(topic, titel_norm) DO UPDATE SET
|
||||
nennungen = nennungen + 1, quellen = excluded.quellen, updated_at = excluded.updated_at""",
|
||||
(topic, titel_norm, titel, beschreibung, json.dumps(quellen or [], ensure_ascii=False), _now()),
|
||||
reader = (SELECT json_group_array(v) FROM (
|
||||
SELECT value AS v FROM json_each(bausteine.reader)
|
||||
UNION SELECT ? WHERE ? IS NOT NULL)),
|
||||
nennungen = (SELECT count(*) FROM (
|
||||
SELECT value AS v FROM json_each(bausteine.reader)
|
||||
UNION SELECT ? WHERE ? IS NOT NULL)),
|
||||
quellen = excluded.quellen, updated_at = excluded.updated_at""",
|
||||
(topic, titel_norm, titel, beschreibung,
|
||||
json.dumps(quellen or [], ensure_ascii=False),
|
||||
json.dumps([rid] if rid else [], ensure_ascii=False), _now(),
|
||||
rid, rid, rid, rid),
|
||||
)
|
||||
await db.commit()
|
||||
|
||||
@@ -738,6 +759,7 @@ async def list_bausteine(topic: str, status: str | None = None) -> list[dict]:
|
||||
for row in rows:
|
||||
d = _row_to_dict(row, cursor)
|
||||
d["quellen"] = json.loads(d.get("quellen") or "[]")
|
||||
d["reader"] = json.loads(d.get("reader") or "[]")
|
||||
out.append(d)
|
||||
return out
|
||||
|
||||
|
||||
Reference in New Issue
Block a user