Skip to content

Graph Query

This example is a standalone script. It creates a small relational dataset, defines an AkasicDB graph, creates the graph, and then runs Cypher from Python.

Install

pip install "akasicdb[sdk]"

Example

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()