12.2 Using Autonomous Database Graph Client

Using the AdbGraphClient API, you can access Graph Studio features in Autonomous Database programmatically using the Oracle Graph Client or through your Java or Python application.

This API provides the following capabilities:

  • Authenticate with Autonomous Database
  • Manage the Graph Studio environment
  • Execute graph queries and algorithms against the graph server (PGX)
  • Execute graph queries directly against Oracle Database

To use the AdbGraphClient API, you must have access to Oracle Graph Client installation. The API is provided by the Oracle Graph Client library which is a part of the Oracle Graph Server and Client distribution. See Installing Oracle Graph Client on how to install and get started with the graph client shell CLIs for Java or Python.

Also, prior to using the Autonomous Database Graph Client, ensure you meet all the prerequisite requirements explained in Prerequisites for Using Autonomous Database Graph Client.
The following example shows using the AdbGraphClient API to establish a connection to Graph Studio, start an environment with allocated memory, load a PGQL property graph into memory, execute PGQL queries and run algorithms against the graph.

Note:

See the Javadoc and Python API Reference for more information on AdbGraphClient API.
  1. Start the interactive graph shell CLI and connect to your Autonomous Database instance with the AdbGraphClient using one of the following methods:
    Configuring the AdbGraphClient using Tenancy Details
    cd /opt/oracle/graph
    ./bin/opg4j --no_connect
    For an introduction type: /help intro
    Oracle Graph Server Shell 24.2.0
    opg4j> import oracle.pg.rdbms.*
    opg4j> var config = AdbGraphClientConfiguration.builder()
    opg4j> config.database("<DB_name>")
    opg4j> config.tenancyOcid("<tenancy_OCID>")
    opg4j> config.databaseOcid("<database_OCID>")
    opg4j> config.username("ADBDEV")
    opg4j> config.password("<password_for_ADBDEV>")
    opg4j> config.endpoint("https://<hostname-prefix>.adb.<region>.oraclecloudapps.com/")
    opg4j> var client = new AdbGraphClient(config.build())
    client ==> oracle.pg.rdbms.AdbGraphClient@7b8d1537
    import oracle.pg.rdbms.*;
     
    var config = AdbGraphClientConfiguration.builder();
    config.tenancyOcid("<tenancy_OCID>");
    config.databaseOcid("<database_OCID>");
    config.database("<DB_name>");
    config.username("ADBDEV");
    config.password("<password_for_ADBDEV>");
    config.endpoint("https://<hostname-prefix>.adb.<region>.oraclecloudapps.com/");
     
    var client = new AdbGraphClient(config.build());
    cd /opt/oracle/graph 
    ./bin/opg4py --no_connect
    Oracle Graph Server Shell 24.2.0
    >>> from opg4py.adb import AdbClient
    >>> config = {
    ...          'tenancy_ocid': '<tenancy_OCID>',
    ...          'database': '<DB_name>',
    ...          'database_ocid': '<DB_OCID>',
    ...          'username': 'ADBDEV',
    ...          'password': '<password_for_ADBDEV>',
    ...          'endpoint': 'https://<hostname-prefix>.adb.<region>.oraclecloudapps.com/'
    ... }
    >>> client = AdbClient(config)
    Configuring the AdbGraphClient using JDBC Connection

    You can also configure the AdbGraphClient to use a JDBC connection to connect to your Autonomous Database instance (as shown in the following code). See Connect with JDBC Thin Driver in Using Oracle Autonomous Database Serverless on how to obtain the JDBC URL to connect to the Autonomous Database.

    However, ensure that you have READ access to the v$pdbs view in your Autonomous Database instance. By default, the ADMIN user has READ access to the v$pdbs view. For all other users (non-administrator users), the READ access can be granted by the ADMIN (GRANT SELECT ON v$pdbs TO <user>).

    import oracle.pg.rdbms.*
    opg4j> var conn = DriverManager.getConnection(<jdbcUrl>, <username>, <password>)
    opg4j> var config = AdbGraphClientConfiguration.fromConnection(conn, <password>)
    opg4j> var client = new AdbGraphClient(config)
    import oracle.pg.rdbms.*;
    AdbGraphClientConfiguration config = AdbGraphClientConfiguration.fromCredentials(<jdbcUrl>, <username>, <password>);
    AdbGraphClient client = new AdbGraphClient(config);
    >>> from opg4py.adb import AdbClient
    >>> client = AdbClient.from_connection(<jdbcUrl>, <username>, <password>)
  2. Start the PGX server environment with the desired memory as shown in the following code.
    This submits a job in Graph Studio for environment creation. job.get() waits for the environment to get started. You can always verify if the environment has started successfully with client.isAttached(). The method returns a boolean true if the environment is running.

    However, you can skip the step of creating an environment, if client.isAttached() returns true in the first step of the code.

    opg4j> client.isAttached()
    $9 ==> false
    opg4j> var job=client.startEnvironment(10)
    job ==> oracle.pg.rdbms.Job@117e9a56[Not completed]
    opg4j> job.get()
    $11 ==> null
    opg4j> job.getName()
    $11 ==> "Environment Creation - 16 GBs"
    opg4j> job.getType()
    $12 ==> ENVIRONMENT_CREATION
    opg4j> job.getCreatedBy()
    $13 ==> "ADBDEV"
    opg4j> client.isAttached()
    $11 ==> true
     if (!client.isAttached()) {
             var job = client.startEnvironment(10);
             job.get();
             System.out.println("job details: name=" + job.getName() + "type= " + job.getType() +"created_by= " + job.getCreatedBy());
          }
    job details: name=Environment Creation - 16 GBstype= ENVIRONMENT_CREATIONcreated_by= ADBDEV
    >>> client.is_attached()
    False
    >>> job = client.start_environment(10)
    >>> job.get()
    >>> job.get_name()
    'Environment Creation - 16 GBs'
    >>> job.get_created_by()
    'ADBDEV'
    >>> client.is_attached()
    True
    
  3. Create an instance and a session object as shown:
    opg4j> var instance = client.getPgxInstance()
    instance ==> ServerInstance[embedded=false,baseUrl=https://<hostname-prefix>.adb.<region>.oraclecloudapps.com/graph/pgx]
    opg4j> var session = instance.createSession("AdbGraphSession")
    session ==> PgxSession[ID=c403be26-ad0c-45cf-87b7-1da2a48bda54,source=AdbGraphSession]
    ServerInstance instance = client.getPgxInstance();
    PgxSession session = instance.createSession("AdbGraphSession");
    >>> instance = client.get_pgx_instance()
    >>> session = instance.create_session("adb-session")
  4. Load a PGQL property graph from your Autonomous Database instance into memory.
    opg4j> var graph = session.readGraphByName("BANK_GRAPH", GraphSource.PG_PGQL)
    graph ==> PgxGraph[name=BANK_GRAPH,N=1000,E=5001,created=1647800790654]
    PgxGraph graph = session.readGraphByName("BANK_GRAPH", GraphSource.PG_PGQL);
    >>> graph = session.read_graph_by_name("BANK_GRAPH", "pg_pgql")
  5. Create an Analyst and execute a Pagerank algorithm on the graph as shown:
    opg4j> session.createAnalyst().pagerank(graph)
    $16 ==> VertexProperty[name=pagerank,type=double,graph=BANK_GRAPH]
    session.createAnalyst().pagerank(graph);
    >>> session.create_analyst().pagerank(graph)
    VertexProperty(name: pagerank, type: double, graph: BANK_GRAPH)
  6. Execute a PGQL query on the graph and print the result set as shown:
    opg4j> graph.queryPgql("SELECT a.acct_id AS source, a.pagerank, t.amount, b.acct_id AS destination FROM MATCH (a)-[t]->(b) ORDER BY a.pagerank DESC LIMIT 3").print()
    PgqlResultSet rs = graph.queryPgql("SELECT a.acct_id AS source, a.pagerank, t.amount, b.acct_id AS destination FROM MATCH (a)-[t]->(b) ORDER BY a.pagerank DESC LIMIT 3");
    rs.print();
    >>> rs = graph.query_pgql("SELECT a.acct_id AS source, a.pagerank, t.amount, b.acct_id AS destination FROM MATCH (a)-[t]->(b) ORDER BY a.pagerank DESC LIMIT 3").print()
    On execution, the query produces the following output:
    +------------------------------------------------------+
    | source | pagerank             | amount | destination |
    +------------------------------------------------------+
    | 387    | 0.007302836252205922 | 1000.0 | 188         |
    | 387    | 0.007302836252205922 | 1000.0 | 374         |
    | 387    | 0.007302836252205922 | 1000.0 | 577         |
    +------------------------------------------------------+
    
  7. Optionally, you can execute a PGQL query directly against the graph in the database as shown in the following code.
    In order to establish a JDBC connection to the database, you must download the wallet and save it in a secure location. See JDBC Thin Connections with a Wallet on how to determine the JDBC URL connection string.
    opg4j> String jdbcUrl="jdbc:oracle:thin:@<tns_alias>?TNS_ADMIN=<path_to_wallet>"
    opg4j> var conn = DriverManager.getConnection(jdbcUrl,"ADBDEV","<password_for_ADBDEV>")
    conn ==> oracle.jdbc.driver.T4CConnection@36ee8c7b
    opg4j> var pgqlConn = PgqlConnection.getConnection(conn)
    pgqlConn ==> oracle.pg.rdbms.pgql.PgqlConnection@5f27d271
    opg4j> var pgqlStmt = pgqlConn.createStatement()
    pgqlStmt ==> oracle.pg.rdbms.pgql.PgqlExecution@4349f52c
    opg4j> pgqlStmt.executeQuery("SELECT a.acct_id AS source, t.amount, b.acct_id AS destination FROM MATCH (a)-[t]->(b) ON BANK_GRAPH LIMIT 3").print()
    import oracle.pg.rdbms.pgql.PgqlConnection;
    import oracle.pg.rdbms.pgql.PgqlStatement;
    import oracle.pg.rdbms.pgql.PgqlResultSet;
    import oracle.pgx.api.*;
    import oracle.pg.rdbms.GraphServer;
    import oracle.pg.rdbms.pgql.jdbc.PgqlJdbcRdbmsDriver;
    ….
    DriverManager.registerDriver(new PgqlJdbcRdbmsDriver());
    String jdbcUrl="jdbc:oracle:thin:@<tns_alias>?TNS_ADMIN=<path_to_wallet>";
    Connection conn = DriverManager.getConnection(jdbcUrl,"ADBDEV","<password_for_ADBDEV>");
    PgqlConnection pgqlConn = PgqlConnection.getConnection(conn);
    PgqlStatement pgqlStmt = pgqlConn.createStatement();
    PgqlResultSet rs = pgqlStmt.executeQuery("SELECT a.acct_id AS source, t.amount, b.acct_id AS destination FROM MATCH (a)-[t]->(b) ON BANK_GRAPH LIMIT 3");
    rs.print();
    >>> jdbcUrl = "jdbc:oracle:thin:@<tns_alias>?TNS_ADMIN=<path_to_wallet>"
    >>> pgql_conn = opg4py.pgql.get_connection("ADBDEV","<password_for_ADBDEV>", jdbcUrl)
    >>> pgql_statement = pgql_conn.create_statement()
    >>> pgql_statement.execute_query("SELECT a.acct_id AS source, t.amount, b.acct_id AS destination FROM MATCH (a)-[t]->(b) ON BANK_GRAPH LIMIT 3").print()
    On execution, the query produces the following output:
    +-------------------------------+
    | SOURCE | AMOUNT | DESTINATION |
    +-------------------------------+
    | 1000   | 1000   | 921         |
    | 1000   | 1000   | 662         |
    | 1000   | 1000   | 506         |
    +-------------------------------+
    
  8. Close the session after executing all graph queries as shown:
    opg4j> session.close()
    opg4j> session.close();
    >>> session.close()

12.2.1 Prerequisites for Using Autonomous Database Graph Client

As a prerequisite requirement to get started with the AdbGraphClient API, you must:

  • Provision an Autonomous Database instance in Oracle Autonomous Database.
  • Obtain the following information if you are configuring the AdbGraphClient using the tenancy details. Otherwise, skip this step.
    Key Description More Information
    tenancy OCID The Oracle Cloud ID (OCID) of your tenancy To determine the OCID for your tenancy, see "Where to Find your Tenancy's OCID" in: Oracle Cloud Infrastructure Documentation.
    database Database name of your Autonomous Database instance
    1. Open the OCI console and click Oracle Database in the left navigation menu.
    2. Click Autonomous Database and navigate to the Autonomous Databases page.
    3. Select the required Autonomous Database under the Display Name column and navigate to the Autonomous Database Details page.
    4. Note the Database Name under "General Information" in the Autonomous Database Information tab.
    database OCID The Oracle Cloud ID (OCID) of your Autonomous Database
    1. Open the OCI console and click Oracle Database in the left navigation menu.
    2. Click Autonomous Database and navigate to the Autonomous Databases page.
    3. Select the required Autonomous Database under the Display Name column and navigate to the Autonomous Database Details page.
    4. Note the Database OCID under "General Information" in the Autonomous Database Information tab.
    username Graph enabled Autonomous Database username, used for logging into Graph Studio See Create a Graph User for more information.
    password Database password for the graph user If the password for a graph user is forgotten, then you can always reset password for the graph user by logging into Database Actions as the ADMIN user. See Edit User for more information.
    endpoint Graph Studio endpoint URL
    1. Select your Autonomous Database instance and navigate to the Autonomous Database Details page.
    2. Click the Tools tab.
    3. Click on Graph Studio.
    4. Copy the URL of the new tab that opens the Graph Studio login screen.
    5. Edit the URL to remove the part after oraclecloudapps.com to obtain the endpoint URL.

      For example, the following shows the format of a sample endpoint URL:

      https://<hostname_prefix>.adb.<region_identifier>.oraclecloudapps.com
  • Access Graph Studio and create a PGQL property graph.
  • Download, install and start the Oracle Graph Java or Python client.

12.2.2 Using the PGX JDBC Driver with the AdbGraphClient API

Starting from Graph Server and Client Release 24.1.0, you can use the PGX JDBC driver with the AdbGraphClient API to query graphs stored in the memory of the graph server in Graph Studio on Autonomous Database.

To use the PGX JDBC driver to connect to your Autonomous Database instance, note the following:

  • Register the PGX JDBC driver with the DriverManager:
    import java.sql.DriverManager;
    import oracle.pgx.jdbc.PgxJdbcDriver;
    ...
    DriverManager.registerDriver(new PgxJdbcDriver());
  • Use one of the following two ways to establish the connection using the PGX JDBC Driver:
    • Using Properties
      properties = new Properties();
      properties.put("tenancy_ocid", "<tenancy_OCID>");
      properties.put("database_ocid", "<database_OCID>");
      properties.put("database", "<database_name>");
      properties.put("username", "<username>");
      properties.put("password", "<password>");
      Connection connection = DriverManager.getConnection("jdbc:oracle:pgx:https://<hostname-prefix>.adb.<region>.oraclecloudapps.com", properties);
    • Using a Wallet
      Connection connection = DriverManager.getConnection("jdbc:oracle:pgx:@<db_TNS_name>?TNS_ADMIN=<path_to_wallet>", "<ADB_username>", "<ADB_password>")

    Note that the JDBC URL in the preceding code samples, use jdbc:oracle:pgx: as the prefix.

Example 12-1 Using the PGX JDBC Driver to run graph queries in Autonomous Database

The following example establishes a connection using the PGX JDBC driver to connect to an Autonomous Database instance, starts the compute environment in Graph Studio, loads a graph into the graph server (PGX), creates a statement, and runs a PGQL query on the graph.

import java.sql.*;
import oracle.pgx.jdbc.*;
import oracle.pg.rdbms.*;
import oracle.pgx.api.*;

public class AdbPgxJdbc {

  public static void main(String[] args) throws Exception {

    DriverManager.registerDriver(new PgxJdbcDriver());


    try (Connection conn = DriverManager.getConnection("jdbc:oracle:pgx:@<db_TNS_name>?TNS_ADMIN=<path_to_wallet>","ADB_username","<ADB_password>")) {
      AdbGraphClient client = conn.unwrap(AdbGraphClient.class);
      if (!client.isAttached()) {
        var job = client.startEnvironment(10);
         job.get();
         System.out.println("job details: name=" + job.getName() + "type= " + job.getType() +"created_by= " + job.getCreatedBy());
        }
      PgxSession session = conn.unwrap(PgxSession.class);
      PgxGraph graph = session.readGraphByName("BANK_PGQL_GRAPH", GraphSource.PG_PGQL);
      Statement stmt = conn.createStatement();
      ResultSet rs = stmt.executeQuery("SELECT * "+
                                         "FROM GRAPH_TABLE ( BANK_PGQL_GRAPH "+
                                         "MATCH (a IS ACCOUNTS) -[e IS TRANSFERS]-> (b IS ACCOUNTS) "+
                                         "WHERE a.ID = 179 AND b.ID = 688 "+
                                         "COLUMNS (e.AMOUNT AS AMOUNT ))");
      while(rs.next()){
        System.out.println("AMOUNT = " + rs.getLong("AMOUNT"));
      }

    }
  }
}

The resulting output of the preceding code is as shown:

AMOUNT = 7562