OCI上にgraph Serverを作ってみた#1

# はじめに
この記事はOCI上でのリソースの作成から、サーバーへ接続してグラフを作成してクエリまでを実行してみました。

[Analyze, Query, and Visualize Graphs in Oracle Database Workshop](https://apexapps.oracle.com/pls/apex/dbpm/r/livelabs/view-workshop?wid=686) の記事を参考にOCI上でAutonomous Databaseと接続したGraph Serverを作成しています。

また、今回利用するリソースはOCIの**無料トライアル環境でも構築可能**な内容になっています。

# 前提条件
**-OCIのアカウントを持っていること**
**-ssh接続のための秘密鍵と公開鍵を持っていること**
上記2点は元記事の[Getting StartedおよびLab1:Create SSH Keys](https://apexapps.oracle.com/pls/apex/dbpm/r/livelabs/workshop-attendee-2?p210_workshop_id=686&p210_type=3&session=5524394194438)で確認可能ですが、基本的な点のため、今回は割愛します。

# 今回の構成
Autonomous DatabaseとOCIマーケットプレイスからプロビジョニングできるグラフサーバーを利用します。

# Autonomous Databaseを作成する
1.Oracle Cloudにログインする
2.ログイン後、左側のメニューから **Oracle Database** > **Autonomous Database**をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706384/6c6a8867-aaff-0d6a-fc74-4d9681874c8e.png)
3. **Autonomous Databaseの作成**ボタンを押して、作成画面へ移動します。
4.  基本的な情報を入力します
- **コンパートメント: 任意のコンパートメント**を選択してください
- **表示名: ATPGraph**(お好きな覚えやすい名前で大丈夫です)
- **データベース名: ATPGRAPH** (条件に合ったお好きな覚えやすい名前で大丈夫です)
- **ワークロードタイプ: トランザクション処理**(データウェアハウスでも特に問題はないです)
- **デプロイメント・タイプの選択: 共有インフラストラクチャ**(構成が可能であれば専用インフラストラクチャでも問題ないです)
 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706384/07b1d79e-9dd9-3521-1918-22297fe6f8d4.png)

- **データベース・バージョンの選択:19cか21c**を選択
- **OCPU数:利用したいCPUの数**を選びます。(1でも今回のラボでは問題はありません)
無料環境の場合は**Always Freeの構成オプションのみを表示**というボタンがあるので活用してください。( 1 CPU と 20 GBが選択可能なはずです。) 
- **OCPUの自動スケーリング:今回はオフ**にします
- **ストレージ: 任意のサイズ**を選択可能です
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706384/adc8e2b4-b58d-851e-587b-7875fdf87c8d.png)
- **パスワード:条件に合う任意のもの**を設定
- **ネットワークアクセスの選択:すべての場所からのセキュア・アクセス**を選択
- **ライセンス・タイプの選択:ライセンス込み**を選択(すでにライセンスをお持ちの場合はBYOLを選択可能です)
問題がなければ上記内容で左下の**Autonomous Databaseの作成**をクリックします。

数分間でプロビジョニングが完了します。
プロビジョニング中は黄色い画面で、完了すると緑色の画面になります
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706384/809f7456-b5ee-ccf3-b6bc-28ea00bd9b38.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706384/b0e19b63-0028-bd1a-dbfb-dd0af41b4400.png)


# グラフサーバーを作成する
このグラフサーバーを作成するステップでは
- グラフサーバーを構成するためのネットワークの作成
- OCIマーケットプレイスからサーバーのデプロイ
- グラフサーバーがADBと接続するためのウォレットの構成
までの操作を行います。

## ネットワークを作成
1.VCNウィザードを利用して、基本的なネットワーキングに必要なリソースを作成します。
OCIのメニュー画面から、**ネットワーキング**>**仮想クラウド・ネットワーク** をクリックします
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706384/a2b5ada5-828b-2f8a-e7f1-1505bf060ae0.png)

仮想クラウド・ネットワークのトップ画面で、**VCNウィザードの起動**を選択します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706384/ea512446-b1a2-ec06-6c6a-ee9ad810b311.png)
するとVCNウィザードの起動の詳細画面が出るので、**インターネット接続性を持つVCNの作成**を選択して、左下の**VCNウィーザードの起動**ボタンをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706384/80a929ec-820f-9b1d-038e-eb1cd1020a14.png)
ウィザード起動後、構成画面に移動するので、**VCN名のみ任意のものに設定し、そのほかの設定はデフォルトのまま**にして、**次へボタンをクリック**して作成を完了させます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706384/ad6f65ff-e64a-7c01-86d6-199b793421d1.png)
準備ができ次第、ネットワークが完成します。

2.ネットワークでグラフ接続のためのポートを開放する
グラフサーバーは**7007番ポートを利用して通信**を行うため、先ほど作成したネットワークのポートを開放します。
ポートの開放は、メニューバーの**ネットワーキング**>**仮想クラウドネットワーク**の画面に移動して、**先ほど作成したネットワークをクリック**します。(名前の例はvcn1ですが、画像ではseoulvcnとなっています)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706384/c8f2a4db-785f-bfb6-a414-79e4898b74a6.png)
VCNの詳細画面が表示されるので、ここで**パブリック・サブネットをクリック**します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706384/02b2b197-c644-cd26-ed7f-657c4510a5b9.png)


デフォルトセキュリティリストを選択し
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706384/c3335151-e3dd-14db-a799-6cd617400dbe.png)イングレス・ルールの詳細画面から、**イングレス・ルールの追加**ボタンを選択して、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706384/e7f26362-6210-5e50-5d76-4310aec168ab.png)

下記のイングレスルールを追加します。
- **ソース・タイプ: CIDR**
- **ソースCIDR: 0.0.0.0/0** (**テスト環境のみ推奨**、実際の環境では任意のソースに置き換えてください)
- **IPプロトコル: TCP**
- **ソース・ポート範囲: All**
- **宛先ポート範囲: 7007**
- **説明: For Graph Server**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706384/e2c2e1fa-7cc4-eeb3-11f3-6da014b31c51.png)

これで7007番ポートも通信可能となりました。

## マーケットプレイスからグラフサーバーを作成する

マーケットプレイスイメージを活用することで、ユースケースに応じて必要なソフトウェアがデプロイ後すぐに使い始めることができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706384/02ef0931-0c07-2463-285e-668003a7281e.png)
1. クラウドコンソールの**マーケットプレイス**のタブに移動する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706384/8f67195d-5406-fdc2-7580-59b1dc7f0045.png)

1. 検索欄から"**Graph Server and Client**"を検索して、該当イメージを選択する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706384/058a5319-fa2a-f8e3-6161-d0bc6d054af9.png)

1. **バージョン**と利用したい**コンパートメント**を選択して、**スタックの起動**をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706384/be1953f8-09dd-ead8-d1f6-7fbf3c10fcbe.png)

1. スタックが起動されたら、特に変更せずに**次へ**ボタンを押す

1. **変数の構成**画面では下記の設定を入力
- **任意のリソース名**、**コンパートメント**と**Availability Domein**
- **任意のシェイプ**(Always freeプランでは**VM.Standard.E2.1.Micro**が選択可)
- **SSH公開鍵を貼り付ける**
- ネットワークでは**前のステップで作成したネットワークを指定(vcn1)**
- **JDBC URL: jdbc:oracle:thin:@atpgraph_low?TNS_ADMIN=/etc/oracle/graph/wallets**

※入力する**JDBC URLの意味**について
これはこの後のステップで、グラフサーバーにアップロードする予定の**Autonomous Databaseの認証用ウォレット**を置く予定の**ディレクトリへのTNS_ADMINのエントリーポイント**です。
データベース名を例で示されているatpgraphとは**違う名前で命名した場合は、置き換えてください**。(myatpgraphというデータベース名の場合、@myatpgraph_lowにURLの例を置き換える)

設定項目を入力後、**次へ**を押して、作成を開始します。完了すると緑色の画面に変わります。2,3分程度で完了される予定です。


※Always-free Compute VM は、ホームリージョンにのみ作成できます。以前にalways-free compute VMを作成している場合は、以前のVMと同じアベイラビリティドメインのみに新たなVMインスタンスを作成することが可能なため、エラー時にはご確認ください。

- スタックを閉じる前にアクセスに必要になる**publicip**と**graphvizpublic_url**の値をログからメモしてください

## ADBウォレットをダウンロード
1. OCIコンソールから **Oracle Database** > **Autonomous Database** へ移動
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706384/4508fe51-e495-c7e8-4290-3174fde38eb1.png)

1. **DB接続**のボタンを押して、ウォレットをダウンロード
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706384/1138ece0-4253-3eba-9c54-8e505c9adc80.png)

1. パスワードを入力して、zip形式のウォレットをダウンロード
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706384/f34e28d5-22a9-b4c5-819d-68b837aa303a.png)
ウォレットをダウンロードする時にはe** データベース作成時に指定したパスワード** の入力が求められるので入力します。
デフォルトのファイル名は Wallet_.zipです

## ADBウォレットをグラフサーバーにアップロード
サーバーにファイルをアップロードする方式はほかにもありますが、ここではscpを利用してダウンロードしたウォレットをグラフサーバーにアップロードします。

1. サーバーにウォレットをアップロード

    ```terminal
    scp -i <private_key> <Wallet_database_name>.zip opc@<public_ip_for_compute>:/etc/oracle/graph/wallets

    例)
    scp -i key.pem ~/Downloads/Wallet_ATPGRAPH.zip opc@203.0.113.14:/etc/oracle/graph/wallets
   ```

1. アップロード済のウォレットを解凍する
     グラフサーバーにSSHで**opc**ユーザーとして、秘密鍵を指定してアクセスします
    ```
    ssh -i <private_key> opc@<public_ip_for_compute>
    例)
    ssh -i key.pem opc@203.0.113.14
    ```

1. ADBウォレットを **/etc/oracle/graph/wallets/** ディレクトリで解凍します

    ```
    cd /etc/oracle/graph/wallets/
    unzip Wallet_ATPGRAPH.zip
    chgrp oraclegraph *
    ```

1. 正しいJDBC URLをOCIのコンピュート作成時に入力しているかを必要であれば確認します
```
cat /etc/oracle/graph/wallets/tnsnames.ora
```
正しければ下記のような値を確認できるはずです
```
atpgraph_low =
    (description=
        (address=
            (https_proxy=proxyhostname)(https_proxy_port=80)(protocol=tcps)(port=1521)
            (host=adwc.example.oraclecloud.com)
        )
        (connect_data=(service_name=adwc1_low.adwc.oraclecloud.com))
        (security=(ssl_server_cert_dn="adwc.example.oraclecloud.com,OU=Oracle BMCS US,O=Oracle Corporation,L=Redwood City,ST=California,C=US"))
)
```

# グラフを利用可能なユーザーを作成する
1. ADBの画面から、**データベースアクションズ**へ移動します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706384/8280a195-5150-b418-4d4f-9aa2aa611a46.png)

1. **ADMIN**ユーザーとしてログインします
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706384/083cd8bb-e33b-0d34-f623-b07aa7a0a8e9.png)

## graph関連の権限を作成する
graphを作成するためには別途**GRAPH_DEVELOPER**や**GRAPH_ADMINISTRATOR**等の権限が必要になります。

1. SQLメニューから、ADMINユーザーとして、下記のロール作成用クエリを入力
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706384/ae87a385-19d1-757f-79e7-06f4541203ac.png)


```sql
DECLARE
  PRAGMA AUTONOMOUS_TRANSACTION;
  role_exists EXCEPTION;
  PRAGMA EXCEPTION_INIT(role_exists, -01921);
  TYPE graph_roles_table IS TABLE OF VARCHAR2(50);
  graph_roles graph_roles_table;
BEGIN
  graph_roles := graph_roles_table(
    'GRAPH_DEVELOPER',
    'GRAPH_ADMINISTRATOR',
    'GRAPH_USER',
    'PGX_SESSION_CREATE',
    'PGX_SERVER_GET_INFO',
    'PGX_SERVER_MANAGE',
    'PGX_SESSION_READ_MODEL',
    'PGX_SESSION_MODIFY_MODEL',
    'PGX_SESSION_NEW_GRAPH',
    'PGX_SESSION_GET_PUBLISHED_GRAPH',
    'PGX_SESSION_COMPILE_ALGORITHM',
    'PGX_SESSION_ADD_PUBLISHED_GRAPH');
  FOR elem IN 1 .. graph_roles.count LOOP
  BEGIN
    dbms_output.put_line('create_graph_roles: ' || elem || ': CREATE ROLE ' || graph_roles(elem));
    EXECUTE IMMEDIATE 'CREATE ROLE ' || graph_roles(elem);
  EXCEPTION
    WHEN role_exists THEN
      dbms_output.put_line('create_graph_roles: role already exists. continue');
    WHEN OTHERS THEN
      RAISE;
    END;
  END LOOP;
EXCEPTION
  when others then
    dbms_output.put_line('create_graph_roles: hit error ');
    raise;
END;
/
```

```sql
GRANT PGX_SESSION_CREATE TO GRAPH_ADMINISTRATOR;
GRANT PGX_SERVER_GET_INFO TO GRAPH_ADMINISTRATOR;
GRANT PGX_SERVER_MANAGE TO GRAPH_ADMINISTRATOR;
GRANT PGX_SESSION_CREATE TO GRAPH_DEVELOPER;
GRANT PGX_SESSION_NEW_GRAPH TO GRAPH_DEVELOPER;
GRANT PGX_SESSION_GET_PUBLISHED_GRAPH TO GRAPH_DEVELOPER;
GRANT PGX_SESSION_MODIFY_MODEL TO GRAPH_DEVELOPER;
GRANT PGX_SESSION_READ_MODEL TO GRAPH_DEVELOPER;
GRANT PGX_SESSION_CREATE TO GRAPH_USER;
GRANT PGX_SESSION_GET_PUBLISHED_GRAPH TO GRAPH_USER;
```

これでグラフに関する権限を設定することができました。

## 新規ユーザーを作成
**データベースアクションズ**画面から、新たに**CUSTOMER_360**というユーザーを作成します。

下記内容を指定します。

- **ユーザー名:CUSTOMER_360**
- **任意のパスワード**
- **グラフ: 有効化**
- **Webアクセス: 有効化**
- **表領域の割り当て制限 :UNLIMITED**
- **付与されたロール**: **GRAPH_DEVELOPER role** と **PGX_SESSION_ADD_PUBLISHED_GRAPH** を追加

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706384/738f2403-efdd-5ea8-6529-8ff7645c7859.png)
下記画面の**PGX_SESSION_ADD_PUBLISHED_GRAPH**グラフロールがないと、作成したグラフを永続化させる権限を持たないユーザーになるので、付与する必要があります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706384/e8f7b03c-ac5a-07e5-f880-d47694552d2f.png)

# ADB上にサンプルデータを作成
次は先ほど作成したCUSTOMER_360ユーザーが利用できる7つのサンプル表とデータの作成をします。
作成予定の表の関係は下記のようになっています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706384/59149bd9-767c-72ba-4f0c-17c0556dc8ad.png)

1. ADBの画面から、**データベースアクションズ**へ移動します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706384/8280a195-5150-b418-4d4f-9aa2aa611a46.png)

1. データベースアクションズへログインする
先ほど新たにユーザーを作成した**データベースアクションズ**にてクエリを行います。前回はADMINとしてログインしましたが、今回は**CUSTOMER_360としてログイン**します。
ログインする際のURLにはCUSTOMER_360としてログインするため、/customer_360/という文字列が含まれているはずです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706384/552946ef-0816-4b17-0068-141e74057b8a.png)

1. テーブルが既に存在する場合、ドロップする
テーブルに余計なデータが含まれていないように、もし既存のテーブルが存在する場合、下記のクエリでテーブルをドロップします。

    ```sql
    DROP TABLE account;
    DROP TABLE customer;
    DROP TABLE merchant;
    DROP TABLE owned_by;
    DROP TABLE parent_of;
    DROP TABLE purchased;
    DROP TABLE transfer;
    ```

1. ACCOUNTテーブルを作成する
    ```sql
    CREATE TABLE account (
    id NUMBER NOT NULL
    , account_no VARCHAR2(20)
    , customer_id NUMBER
    , open_date VARCHAR2(20)
    , balance NUMBER
    , CONSTRAINT account_pk PRIMARY KEY (id)
    );

    INSERT INTO account VALUES (201,'xxx-yyy-201',101,'2015-10-04',1500);
    INSERT INTO account VALUES (202,'xxx-yyy-202',102,'2012-09-13',200);
    INSERT INTO account VALUES (203,'xxx-yyy-203',103,'2016-02-04',2100);
    INSERT INTO account VALUES (204,'xxx-yyy-204',104,'2018-01-05',100);
    INSERT INTO account VALUES (211,'xxx-zzz-211',NULL,NULL,NULL);
    INSERT INTO account VALUES (212,'xxx-zzz-212',NULL,NULL,NULL);
    COMMIT;
    ```

1. CUSTOMERテーブルを作成する
    ```sql
    CREATE TABLE customer (
    id NUMBER NOT NULL,
    name VARCHAR2(20),
    age NUMBER,
    location VARCHAR2(20),
    gender VARCHAR2(20),
    student VARCHAR2(20)
    , CONSTRAINT customer_pk PRIMARY KEY (id)
    );

    INSERT INTO customer VALUES (101,'John',10,'Boston',NULL,NULL);
    INSERT INTO customer VALUES (102,'Mary',NULL,NULL,'F',NULL);
    INSERT INTO customer VALUES (103,'Jill',NULL,'Boston',NULL,NULL);
    INSERT INTO customer VALUES (104,'Todd',NULL,NULL,NULL,'true');
    COMMIT;
    ```

1. MERCHANTテーブルを作成する
    ```sql
    CREATE TABLE merchant (
    id NUMBER NOT NULL
    , name VARCHAR2(20)
    , CONSTRAINT merchant_pk PRIMARY KEY (id)
    );

    INSERT INTO merchant VALUES (301,'Apple Store');
    INSERT INTO merchant VALUES (302,'PC Paradise');
    INSERT INTO merchant VALUES (303,'Kindle Store');
    INSERT INTO merchant VALUES (304,'Asia Books');
    INSERT INTO merchant VALUES (305,'ABC Travel');
    COMMIT;
    ```

1. PARENT_OFテーブルを作成する
    ```sql
    CREATE TABLE parent_of (
    customer_id_parent NUMBER
    , customer_id_child NUMBER
    , CONSTRAINT parent_of_pk PRIMARY KEY (customer_id_parent, customer_id_child)
    );

    INSERT INTO parent_of VALUES (103,104);
    COMMIT;
    ```

1. PURCHASEDテーブルを作成する
    ```sql
    CREATE TABLE purchased (
    id NUMBER
    , account_id NUMBER
    , merchant_id NUMBER
    , amount NUMBER
    , CONSTRAINT purchased_pk PRIMARY KEY (id)
    );

    INSERT INTO purchased VALUES (1001,201,301,800);
    INSERT INTO purchased VALUES (1002,201,302,15);
    INSERT INTO purchased VALUES (1003,202,301,150);
    INSERT INTO purchased VALUES (1004,202,302,20);
    INSERT INTO purchased VALUES (1005,202,304,10);
    INSERT INTO purchased VALUES (1006,203,301,350);
    INSERT INTO purchased VALUES (1007,203,302,20);
    INSERT INTO purchased VALUES (1008,203,303,15);
    INSERT INTO purchased VALUES (1009,204,303,10);
    INSERT INTO purchased VALUES (1010,204,304,15);
    INSERT INTO purchased VALUES (1011,204,305,450);
    COMMIT;
    ```

1. TRANSFERテーブルを作成する
    ```sql
    CREATE TABLE transfer (
    id NUMBER
    , account_id_from NUMBER
    , account_id_to NUMBER
    , amount NUMBER
    , transfer_date VARCHAR2(20)
    , CONSTRAINT transfer_pk PRIMARY KEY (id)
    );

    INSERT INTO transfer VALUES (100001,201,202,200,'2018-10-05');
    INSERT INTO transfer VALUES (100002,211,202,900,'2018-10-06');
    INSERT INTO transfer VALUES (100003,202,212,850,'2018-10-06');
    INSERT INTO transfer VALUES (100004,201,203,500,'2018-10-07');
    INSERT INTO transfer VALUES (100005,203,204,450,'2018-10-08');
    INSERT INTO transfer VALUES (100006,204,201,400,'2018-10-09');
    INSERT INTO transfer VALUES (100007,202,203,100,'2018-10-10');
    INSERT INTO transfer VALUES (100008,202,201,300,'2018-10-10');
    COMMIT;
    ```


# グラフを作成する


1. グラフサーバーにSSHでopcユーザーとして接続
鍵はサーバーを作成するときに預けた公開鍵とペアになるものを使います

    ```sql
    ssh -i <private_key> opc@<public_ip_for_compute>
    例)
    ssh -i key.pem opc@203.0.113.14
    ```

1. グラフクライアントを利用して、グラフを作成、クエリします。

    ```sql
    opg4py -b https://localhost:7007 -u customer_360

   #接続に成功すると下記のような表示になります
   password:

    Oracle Graph Client Shell 21.4.2
    >>>
    ```

 1. グラフを作成する
既存のテーブルからグラフを作成するためのstatementを作成します

    ```
    statement = '''
    CREATE PROPERTY GRAPH "customer_360"
    VERTEX TABLES (
        customer
    , account
    , merchant
    )
    EDGE TABLES (
        account
        SOURCE KEY(id) REFERENCES account
        DESTINATION KEY(customer_id) REFERENCES customer
        LABEL owned_by PROPERTIES (id)
    , parent_of
        SOURCE KEY(customer_id_parent) REFERENCES customer
        DESTINATION KEY(customer_id_child) REFERENCES customer
    , purchased
        SOURCE KEY(account_id) REFERENCES account
        DESTINATION KEY(merchant_id) REFERENCES merchant
    , transfer
        SOURCE KEY(account_id_from) REFERENCES account
        DESTINATION KEY(account_id_to) REFERENCES account
    )
    '''
    ```

1. グラフを作成するためにPGQLのDDLを実行する
Falseと表示されても正しい動きです

    ```sql
    >>> session.prepare_pgql(statement).execute()
    False   # これは期待される結果です
    ```
 
## 新たに作成されたグラフを確認する
引き続きPythonシェルから、先ほど作成されたグラフを確認します。

1. グラフをアタッチする

   ```
    graph = session.get_graph("customer_360")
   ```

1. グラフが作成されているかgraphコマンドで確認する

   ```
    graph

    #成功していれば下記のような表示に
    PgxGraph(name: customer_360, v: 15, e: 24, directed: True, memory(Mb): 0)
   ```

# PGQLでグラフをクエリする
作成されたグラフに対していくつかのクエリを行っていきます

1. ノードのラベル一覧を確認する

   ```
   graph.query_pgql("""
    SELECT DISTINCT LABEL(v) FROM MATCH (v)
   """).print()

    #成功していれば下記のような表示に
    +----------+
    | LABEL(v) |
    +----------+
    | ACCOUNT  |
    | CUSTOMER |
    | MERCHANT |
    +----------+
   ```

1. それぞれのラベルに何個のノードがあるのか数える

   ```
   graph.query_pgql("""
    SELECT COUNT(v), LABEL(v) FROM MATCH (v) GROUP BY LABEL(v)
   """).print()

    +---------------------+
    | COUNT(v) | LABEL(v) |
    +---------------------+
    | 5        | MERCHANT |
    | 6        | ACCOUNT  |
    | 4        | CUSTOMER |
    +---------------------+
   ```


1. エッジのラベル一覧を確認する

   ```
   graph.query_pgql("""
    SELECT DISTINCT LABEL(e) FROM MATCH ()-[e]->()
   """).print()

    +-----------+
    | LABEL(e)  |
    +-----------+
    | OWNED_BY  |
    | PARENT_OF |
    | PURCHASED |
    | TRANSFER  |
    +-----------+
   ```


1. それぞれのラベルに何個のエッジがあるのか数える

   ```
   graph.query_pgql("""
    SELECT COUNT(e), LABEL(e) FROM MATCH ()-[e]->() GROUP BY LABEL(e)
   """).print()

    +----------------------+
    | COUNT(e) | LABEL(e)  |
    +----------------------+
    | 4        | OWNED_BY  |
    | 8        | TRANSFER  |
    | 1        | PARENT_OF |
    | 11       | PURCHASED |
    +----------------------+
   ```

# グラフを永続化させる
前のステップで作成されてたグラフは、現行セッションのみで有効なデフォルトではプライベートなグラフです。新たなセッションでもグラフを参照するためには、グラフをpublishする必要があります。

1.グラフをpublishする
※この操作にはPGX_SESSION_ADD_PUBLISHED_GRAPHロールが必要です。ロールが付与されていない場合、ADMINユーザーでデータベースのユーザーに権限を付与してから、Pythonシェルに再接続する必要があります。
   ```
   graph.publish()
   ```

グラフサーバーが再起動や停止されない限り、次からは下記のコマンドでメモリ内に保存されたグラフに再読み込み不要でアクセスすることが可能になります。
   ```
   graph = session.get_graph("customer_360")
   ```

# まとめ
今回はセットアップから簡単なクエリまで実行してみました。次はより詳しいグラフの分析や可視化方法を実行してみましょう!