Graph Query¶
이 예제는 standalone script입니다. 작은 relational dataset을 만들고, AkasicDB graph를 정의 및 생성한 뒤 Python에서 Cypher를 실행합니다.
설치¶
예제¶
import psycopg
from akasicdb.graph import execute_cypher, wrap_cypher_query
from akasicdb.sdk import GraphQuery, node
DB_URL = "postgresql://postgres:mysecretpassword@localhost:5432/postgres"
GRAPH_NAME = "python_graph_example"
def execute_ignoring_errors(conn, sql):
try:
conn.execute(sql)
conn.commit()
except psycopg.Error:
conn.rollback()
def setup_graph():
with psycopg.connect(DB_URL) as conn:
conn.execute("CREATE EXTENSION IF NOT EXISTS akasicdb")
conn.execute("SELECT akasicdb_admin.initialize()")
conn.commit()
execute_ignoring_errors(
conn,
f"SELECT akasicdb.delete_graph('{GRAPH_NAME}', remove_definition:=true)",
)
conn.execute("DROP TABLE IF EXISTS python_graph_read")
conn.execute("DROP TABLE IF EXISTS python_graph_article")
conn.execute("DROP TABLE IF EXISTS python_graph_reader")
conn.execute("""
CREATE TABLE python_graph_reader (
reader_id integer PRIMARY KEY,
name varchar(40)
)
""")
conn.execute("""
CREATE TABLE python_graph_article (
article_id integer PRIMARY KEY,
title varchar(80)
)
""")
conn.execute("""
CREATE TABLE python_graph_read (
reader_id integer REFERENCES python_graph_reader(reader_id),
article_id integer REFERENCES python_graph_article(article_id)
)
""")
conn.execute("""
INSERT INTO python_graph_reader (reader_id, name)
VALUES (1, 'Alice'), (2, 'Grace')
""")
conn.execute("""
INSERT INTO python_graph_article (article_id, title)
VALUES (10, 'Vector Search'), (20, 'Graph Query')
""")
conn.execute("""
INSERT INTO python_graph_read (reader_id, article_id)
VALUES (1, 10), (1, 20), (2, 20)
""")
conn.execute(f"SELECT akasicdb.define_graph('{GRAPH_NAME}')")
conn.execute(f"""
SELECT akasicdb.define_vertex(
'{GRAPH_NAME}',
'v_reader',
ARRAY['reader_id integer', 'name varchar(40)'],
'python_graph_reader'
)
""")
conn.execute(f"""
SELECT akasicdb.define_vertex(
'{GRAPH_NAME}',
'v_article',
ARRAY['article_id integer', 'title varchar(80)'],
'python_graph_article'
)
""")
conn.execute(f"""
SELECT akasicdb.define_edge(
'{GRAPH_NAME}',
'viewed',
'v_reader',
'v_article',
null,
'SELECT null FROM python_graph_reader r, python_graph_read ra, python_graph_article a '
'WHERE r.reader_id = ra.reader_id AND a.article_id = ra.article_id',
'python_graph_reader r',
'python_graph_article a'
)
""")
conn.execute(f"SELECT akasicdb.create_graph('{GRAPH_NAME}')")
conn.commit()
def cleanup_graph():
with psycopg.connect(DB_URL) as conn:
execute_ignoring_errors(
conn,
f"SELECT akasicdb.delete_graph('{GRAPH_NAME}', remove_definition:=true)",
)
conn.execute("DROP TABLE IF EXISTS python_graph_read")
conn.execute("DROP TABLE IF EXISTS python_graph_article")
conn.execute("DROP TABLE IF EXISTS python_graph_reader")
conn.commit()
setup_graph()
try:
cypher = """
MATCH (r:v_reader)-[:viewed]->(a:v_article)
RETURN r.name AS reader, a.title AS article
"""
print("execute_cypher")
for row in execute_cypher(DB_URL, GRAPH_NAME, cypher):
print(row["reader"], row["article"])
print("wrap_cypher_query")
print(wrap_cypher_query(cypher, GRAPH_NAME))
print("GraphQuery")
rows = (
GraphQuery(DB_URL, GRAPH_NAME)
.match(node("r", "v_reader").rel_out("viewed").node("a", "v_article"))
.return_("r.name AS reader", "a.title AS article")
.execute()
)
for row in rows:
print(row["reader"], row["article"])
finally:
cleanup_graph()