repo.py 3.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. """仓库信息查询 —— 基于仓库地址识别论文元数据的辅助 API."""
  2. from __future__ import annotations
  3. from dataclasses import dataclass
  4. @dataclass(frozen=True)
  5. class RelationRepository:
  6. db_path: str
  7. def fetch_relation_rows(
  8. self, *, focus_id: int | None, paper_ids: set[int | None], limit: int,
  9. ) -> list[tuple[int, int, str, float, str]]:
  10. import sqlite3
  11. if int(limit) <= 0:
  12. return []
  13. rows: list[tuple[int, int, str, float, str]] = []
  14. with sqlite3.connect(self.db_path) as conn:
  15. cur = conn.cursor()
  16. if focus_id is not None:
  17. cur.execute(
  18. """SELECT source_paper_id, target_paper_id, relation, score, evidence
  19. FROM paper_relations
  20. WHERE source_paper_id = ? OR target_paper_id = ?
  21. ORDER BY score DESC, updated_at DESC LIMIT ?""",
  22. (int(focus_id), int(focus_id), int(limit)),
  23. )
  24. else:
  25. ids = sorted(int(x) for x in (paper_ids or set()) if int(x) > 0)
  26. if not ids:
  27. return []
  28. cur.execute("CREATE TEMP TABLE IF NOT EXISTS _kg_pid (id INTEGER PRIMARY KEY)")
  29. cur.execute("DELETE FROM _kg_pid")
  30. cur.executemany("INSERT OR IGNORE INTO _kg_pid(id) VALUES (?)", [(i,) for i in ids])
  31. cur.execute(
  32. """SELECT pr.source_paper_id, pr.target_paper_id, pr.relation, pr.score, pr.evidence
  33. FROM paper_relations pr
  34. INNER JOIN _kg_pid a ON a.id = pr.source_paper_id
  35. INNER JOIN _kg_pid b ON b.id = pr.target_paper_id
  36. ORDER BY pr.score DESC, pr.updated_at DESC LIMIT ?""",
  37. (int(limit),),
  38. )
  39. for sid, tid, rel, score, evidence in cur.fetchall():
  40. rows.append((int(sid), int(tid), str(rel or ""), float(score or 0.0), str(evidence or "")))
  41. return rows
  42. def papers_minimal_by_ids(self, paper_ids: set[int]) -> dict[int, tuple[str, int | None, str | None]]:
  43. import sqlite3
  44. ids = sorted(int(x) for x in paper_ids if int(x) > 0)
  45. if not ids:
  46. return {}
  47. out: dict[int, tuple[str, int | None, str | None]] = {}
  48. with sqlite3.connect(self.db_path) as conn:
  49. cur = conn.cursor()
  50. cur.execute("CREATE TEMP TABLE IF NOT EXISTS _kg_meta (id INTEGER PRIMARY KEY)")
  51. cur.execute("DELETE FROM _kg_meta")
  52. cur.executemany("INSERT OR IGNORE INTO _kg_meta(id) VALUES (?)", [(i,) for i in ids])
  53. cur.execute(
  54. """SELECT p.id, p.title, p.year, p.category
  55. FROM papers p INNER JOIN _kg_meta t ON t.id = p.id"""
  56. )
  57. for rid, title, year, cat in cur.fetchall():
  58. out[int(rid)] = (str(title or ""), int(year) if year is not None else None, str(cat) if cat else None)
  59. return out