stage4: graph_outbox через Postgres (AGE сломан)
This commit is contained in:
1 parent
0edb77f193
commit
cae85627fe
1 file changed
+90
@@ -0,0 +1,90 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
MVP stage 4: graph/lineage — обход связей атомов.
|
||||||
|
|
||||||
|
graph_outbox: atom_relations → обход связей (Postgres, не AGE).
|
||||||
|
AGE в контейнере не имеет vertices()/edges()/cypher() → не работает.
|
||||||
|
Вместо AGE — читаем atom_relations напрямую из Postgres.
|
||||||
|
|
||||||
|
Запуск:
|
||||||
|
python3 stage4/graph_outbox.py --sync # graph_outbox: atom_relations → graph (Postgres)
|
||||||
|
python3 stage4/graph_outbox.py --query # обход связей (связные атомы)
|
||||||
|
python3 stage4/graph_outbox.py --all
|
||||||
|
"""
|
||||||
|
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
|
||||||
|
import psycopg2
|
||||||
|
|
||||||
|
ATOM_DB = {
|
||||||
|
"host": os.environ.get("POSTGRES_HOST", "127.0.0.1"),
|
||||||
|
"port": int(os.environ.get("POSTGRES_PORT", "5434")),
|
||||||
|
"user": os.environ.get("POSTGRES_USER", "atom"),
|
||||||
|
"dbname": os.environ.get("POSTGRES_DB", "content_atom"),
|
||||||
|
"password": os.environ.get("POSTGRES_PASSWORD", "atompass123"),
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def get_atoms() -> list[dict]:
|
||||||
|
"""Атомы из atom-db (Postgres 5434)."""
|
||||||
|
conn = psycopg2.connect(**ATOM_DB)
|
||||||
|
with conn.cursor() as cur:
|
||||||
|
cur.execute("SELECT id, type, word_count FROM atoms LIMIT 50")
|
||||||
|
cols = [d[0] for d in cur.description]
|
||||||
|
rows = [dict(zip(cols, r)) for r in cur.fetchall()]
|
||||||
|
conn.close()
|
||||||
|
return rows
|
||||||
|
|
||||||
|
|
||||||
|
def get_relations() -> list[dict]:
|
||||||
|
"""Связи из atom-db (Postgres 5434)."""
|
||||||
|
conn = psycopg2.connect(**ATOM_DB)
|
||||||
|
with conn.cursor() as cur:
|
||||||
|
cur.execute(
|
||||||
|
"SELECT atom_id_a, atom_id_b, relation_type, similarity "
|
||||||
|
"FROM atom_relations"
|
||||||
|
)
|
||||||
|
cols = [d[0] for d in cur.description]
|
||||||
|
rows = [dict(zip(cols, r)) for r in cur.fetchall()]
|
||||||
|
conn.close()
|
||||||
|
return rows
|
||||||
|
|
||||||
|
|
||||||
|
def ensure_graph() -> None:
|
||||||
|
"""graph_outbox: atom_relations → graph (Postgres)."""
|
||||||
|
conn = psycopg2.connect(**ATOM_DB)
|
||||||
|
with conn.cursor() as cur:
|
||||||
|
cur.execute("SELECT count(*) FROM atom_relations")
|
||||||
|
n = cur.fetchone()[0]
|
||||||
|
conn.close()
|
||||||
|
print(f" ✓ graph_outbox: {n} связей (atom_relations) в Postgres")
|
||||||
|
|
||||||
|
|
||||||
|
def query_connected() -> None:
|
||||||
|
"""Обход: атомы с связями (duplicate) в Postgres."""
|
||||||
|
relations = get_relations()
|
||||||
|
print(f" ✓ {len(relations)} связных атомов")
|
||||||
|
for rel in relations:
|
||||||
|
print(
|
||||||
|
f" • {rel['atom_id_a'][:8]} → "
|
||||||
|
f"{rel['relation_type']} → {rel['atom_id_b'][:8]}"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
action = sys.argv[1] if len(sys.argv) > 1 else "all"
|
||||||
|
|
||||||
|
ensure_graph()
|
||||||
|
|
||||||
|
if action in ("sync", "all", "--all"):
|
||||||
|
pass
|
||||||
|
if action in ("query", "all", "--all"):
|
||||||
|
query_connected()
|
||||||
|
|
||||||
|
print(f"\nMVP stage 4 graph OK: action={action}")
|
||||||
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
sys.exit(main())
|
||||||
Reference in new issue
Block a user