Databases 11 min read

Turn PostgreSQL into a Graph Database with Apache AGE

This guide explains how Apache AGE extends PostgreSQL with OpenCypher‑compatible graph capabilities, covering architecture, installation, storage schema, Cypher‑SQL integration, common graph operations, and a LangChain example that turns natural‑language questions into executable graph queries.

360 Zhihui Cloud Developer
360 Zhihui Cloud Developer
360 Zhihui Cloud Developer
Turn PostgreSQL into a Graph Database with Apache AGE

Introduction

Graph databases excel at handling complex relationships, while PostgreSQL provides robust transactional data management. Apache AGE bridges the two by adding graph functionality to PostgreSQL as an extension, preserving its stability and ecosystem while enabling graph modeling and querying.

Architecture

AGE is a PostgreSQL extension that lets users run graph queries inside an existing relational database. It implements an OpenCypher‑compatible parser, translates Cypher statements into PostgreSQL’s internal query representation, generates graph execution plans, and executes them while retaining PostgreSQL’s ACID guarantees.

Key Features

OpenCypher‑compliant query parser.

Cypher statements are converted to PostgreSQL‑recognizable internal queries.

Generates and executes graph query execution plans.

Executes graph queries efficiently according to the plan.

Fully inherits PostgreSQL’s ACID transaction properties.

Installing the AGE Extension

Compile and install the plugin:

# Compile and install the plugin</code>
<code>yum install gcc glibc glib-common readline readline-devel zlib zlib-devel flex bison</code>
<code>make PG_CONFIG=/usr/local/pgsql17/bin/pg_config install

Load the extension in the database:

# Load the extension</code>
<code>create extension age;</code>
<code>LOAD 'age';</code>
<code>SET search_path = ag_catalog, "$user", public;

Graph Storage Model in PostgreSQL

When a graph is created, AGE creates a namespace in ag_catalog.ag_graph. Two system tables store vertices and edges: _ag_label_vertex and _ag_label_edge. User‑defined vertex and edge tables inherit from these parent tables.

graphid | name      | namespace</code>
<code>---------+-----------+-----------</code>
<code> 17012   | graph_dba | graph_dba

Typical column definitions: name – label name. graph – graph ID. id – label ID. kind – 'v' for vertex, 'e' for edge. relation – underlying PostgreSQL table. seq_name – sequence for auto‑incrementing IDs.

Cypher Syntax Overview

Node : an entity with optional labels and properties.

Relationship : a directed edge between two nodes, also with optional labels and properties.

Core clauses : MATCH (pattern matching), WHERE (filter), RETURN (output).

Combining SQL and Cypher

In AGE, Cypher must be invoked through a SQL function and wrapped in $$ to avoid parser conflicts.

SELECT * FROM cypher('graph_dba', $$</code>
<code>    MATCH (n) RETURN n</code>
<code>$$) AS (n agtype);

Graph Operations

Create / Drop Graph :

SELECT * FROM ag_catalog.create_graph('graph_dba');</code>
<code>SELECT * FROM ag_catalog.drop_graph('graph_dba', true);

Vertex Operations – create multiple vertices :

SELECT * FROM cypher('graph_dba', $$</code>
<code>UNWIND [{name:'zhang3'}, {name:'li4'}] AS row</code>
<code>CREATE (p:Person {name: row.name}) RETURN p</code>
<code>$$) AS (p agtype);

Edge Operations – create a relationship :

SELECT * FROM cypher('graph_dba', $$</code>
<code>MATCH (a:Person {name:'zhang3'}), (b:Person {name:'li4'})</code>
<code>MERGE (a)-[r:FRIENDS {since:2001}]->(b) RETURN r</code>
<code>$$) AS (r agtype);

Query Example – find friends of a person :

SELECT * FROM cypher('graph_dba', $$</code>
<code>MATCH (a:Person {name:'zhang3'})-[r:FRIENDS]->(b:Person) WHERE r.since = 2001 RETURN b</code>
<code>$$) AS (b agtype);

Application Example with LangChain

The following Python snippet shows how to use LangChain’s GraphCypherQAChain together with an AGEGraph instance to translate natural‑language questions into Cypher queries and retrieve results from PostgreSQL + AGE.

from langchain_community.graphs.age_graph import AGEGraph</code>
<code>from langchain.chains import GraphCypherQAChain</code>
<code>from langchain_openai import ChatOpenAI</code>
<code>def main():</code>
<code>    conf = {</code>
<code>        "database": "postgresDB",</code>
<code>        "user": "postgresUser",</code>
<code>        "password": "postgresPW",</code>
<code>        "host": "localhost",</code>
<code>        "port": 5432,</code>
<code>    }</code>
<code>    graph = AGEGraph(graph_name="age_test", conf=conf)</code>
<code>    graph.query("""</code>
<code>        MERGE (m:Movie {name: 'Top Gun'})</code>
<code>        WITH m</code>
<code>        UNWIND ['Tom Cruise', 'Val Kilmer', 'Anthony Edwards', 'Meg Ryan'] AS actor</code>
<code>        MERGE (a:Actor {name: actor})</code>
<code>        MERGE (a)-[:ACTED_IN]->(m)</code>
<code>    """)</code>
<code>    llm = ChatOpenAI(temperature=0)</code>
<code>    chain = GraphCypherQAChain.from_llm(llm, graph=graph, verbose=True, allow_dangerous_requests=True)</code>
<code>    question = "Who played in Top Gun?"</code>
<code>    response = chain.invoke(question)</code>
<code>    print("Natural language query:", response["query"])</code>
<code>    print("Generated answer:", response["result"])</code>
<code>if __name__ == "__main__":</code>
<code>    main()

Conclusion

Apache AGE brings native graph processing to PostgreSQL without requiring a separate database system. By supporting the Cypher query language and leveraging PostgreSQL’s ACID guarantees, it enables practical graph analytics and knowledge‑graph construction within familiar relational‑database environments.

PythonSQLLangChaingraph databasePostgreSQLCypherApache AGE
360 Zhihui Cloud Developer
Written by

360 Zhihui Cloud Developer

360 Zhihui Cloud is an enterprise open service platform that aims to "aggregate data value and empower an intelligent future," leveraging 360's extensive product and technology resources to deliver platform services to customers.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.