Files
politics-tracking/backend/politrack/migrate.py
T
Simon DiesenreiterandClaude Opus 5.5 9da5a1dc48 Politrack: track Austrian politicians from public sources
Initial import of Politrack, a self-hosted service that tracks Austrian
politicians from federal to municipal level - roles, votes, money flows,
statements, meetings, social media and legal proceedings - with every claim
linked to its sources.

- backend: FastAPI + Postgres/pgvector; adapter framework (fetch -> parse ->
  load -> enrich) with robots.txt/TDM-aware fetching, a raw-response archive
  for reparsing, and a claim/evidence model with corroboration
- sources: Parliament, Wikidata, EU Parliament/Commission, Council of
  Ministers, Rechnungshof party reports and donations, procurement, RTR media
  transparency, political ad libraries, WKStA, news feeds, Wikipedia edits,
  Bluesky, Mastodon, public Telegram channels, YouTube and X (official API)
- web: Next.js frontend in German and English with typed API client
- mcp: MCP server for AI agents and RAG
- docs: architecture, data model, sources, legal notes, Unraid deployment and
  contributor guides; Docker Compose setup for Unraid

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 19:47:14 +01:00

36 lines
1.2 KiB
Python

"""Minimal forward-only SQL migration runner (files in backend/migrations)."""
import logging
from pathlib import Path
import psycopg
from psycopg import sql
from politrack.config import get_settings
log = logging.getLogger(__name__)
MIGRATIONS_DIR = Path(__file__).resolve().parent.parent / "migrations"
def migrate() -> None:
settings = get_settings()
with psycopg.connect(settings.database_url, autocommit=False) as conn:
conn.execute(
"CREATE TABLE IF NOT EXISTS schema_migrations ("
" name TEXT PRIMARY KEY, applied_at TIMESTAMPTZ NOT NULL DEFAULT now())"
)
applied = {r[0] for r in conn.execute("SELECT name FROM schema_migrations")}
for path in sorted(MIGRATIONS_DIR.glob("*.sql")):
if path.name in applied:
continue
log.info("applying %s", path.name)
conn.execute(path.read_text(encoding="utf-8"))
conn.execute("INSERT INTO schema_migrations (name) VALUES (%s)", (path.name,))
conn.commit()
if settings.reader_password:
conn.execute(
sql.SQL("ALTER ROLE politrack_reader PASSWORD {}").format(sql.Literal(settings.reader_password))
)
conn.commit()