すべてのプロダクト
Search
ドキュメントセンター

PolarDB:GanosBase へのベクトルデータとラスターデータの高速インポート

最終更新日:Mar 28, 2026

GanosBase は、PolarDB for PostgreSQL (Compatible with Oracle) の空間データベースエンジンです。PolarDB はローカルディスクのない共有ストレージアーキテクチャを採用しているため、標準の PostGIS コマンドラインツール(shp2pgsqlraster2pgsql)を使用してデータをインポートすることはできません。GanosBase は Object Storage Service (OSS) から直接読み取り、代わりにインポート用の SQL 関数を提供します。

インポート方法の選択

開始前にメソッドを選択してください。

データの型方法最適な用途
ベクトル (シェープファイルおよびその他のフォーマット)FDWすべてのベクトルデータのインポート。スクリプト化または自動化されたワークフローに推奨
ベクトル (任意のフォーマット)GIS デスクトップツール (QGIS)GUI からの単発のインポート
ラスター (TIFF、HDF5、NetCDF)ST_ImportFromOSS のソースファイルが削除されてもアクセス可能である必要がある本番データ
ラスター (TIFF、HDF5、NetCDF)ST_CreateRastデータを長期間 OSS に保持し、ソースファイルを自身で管理する探索的クエリ

PostGIS ツールが PolarDB で機能しない理由

PostGIS は、ベクトルデータとラスターデータをロードするためのコマンドラインツールとして shp2pgsqlraster2pgsql を提供しています。これらのツールが PolarDB で機能しない理由は2つあります。

  • サーバーのローカルディスクへの直接アクセスが必要です。PolarDB はローカルディスクを持たない共有ストレージアーキテクチャを採用しています。

  • PostGIS Raster と GanosBase Raster は、内部ストレージ構造が異なります。

ベクトルデータのインポート

FDW を使用したインポート (推奨)

外部データラッパー (FDW) は、外部データソースにアクセスするための PostgreSQL 拡張機能です。GanosBase FDW は、ジオメトリ空間データ型を自動的に Geometry 型にマッピングするため、単一の SQL ステートメントで外部テーブルとローカルテーブルをまとめてクエリできます。

以下の手順では、OSS から poly.shp をローカルの GanosBase テーブルにインポートします。

前提条件

開始する前に、以下が準備できていることを確認してください。

  • PolarDB for PostgreSQL (Compatible with Oracle) インスタンス

  • シェープファイルを含む OSS バケット

  • ご利用の Alibaba Cloud アカウントの AccessKey ID と AccessKey Secret

手順

  1. 必要な拡張機能をインストールします。

    CREATE EXTENSION ganos_spatialref;
    CREATE EXTENSION ganos_geometry;
    CREATE EXTENSION ganos_fdw;
  2. ST_RegForeignTables を使用して、シェープファイルを外部テーブルとして登録します。

    SELECT ST_RegForeignTables('oss://<access_id>:<secret_key>@[<endpoint>]/<bucket>/path_to/poly.shp');

    プレースホルダーを実際の認証情報とファイルパスに置き換えてください。

    プレースホルダー説明
    <access_id>Alibaba Cloud AccessKey IDLTAI5tXxx
    <secret_key>Alibaba Cloud AccessKey SecretxXxXxXx
    <endpoint>OSS エンドポイントoss-cn-hangzhou.aliyuncs.com
    <bucket>OSS バケット名my-geo-bucket
  3. 外部テーブルが登録されたことを確認します。

    SELECT foreign_table_name FROM information_schema.foreign_tables
    ORDER BY foreign_table_name ASC;

    結果にテーブル poly が表示されます。この時点では、poly に対するクエリはオンデマンドで OSS からデータを読み取ります。データはまだデータベースに書き込まれていません。

  4. データをデータベースに書き込むには、次を実行します。

    CREATE TABLE poly_db AS SELECT * FROM poly;

GIS デスクトップツールを使用したインポート

PolarDB for PostgreSQL は PostgreSQL Community Edition と完全な互換性があるため、QGIS やその他の GIS デスクトップツールは修正なしで動作します。ご利用の PolarDB インスタンスを指す PostgreSQL データソース接続を作成し、ツールの組み込みインポート機能を使用します。

ラスターデータのインポート

ST_ImportFrom と ST_CreateRast の違い

どちらの関数も Raster オブジェクトを作成しますが、ピクセルデータの扱い方が異なります。

ST_ImportFromST_CreateRast
データベースに格納されるものラスターメタデータ + ピクセルデータ (デフォルトで 256 x 256 ピクセルでチャンク化)ラスターメタデータのみ (外部イメージへの論理的なマッピング情報)
OSS のソースファイルが削除された場合データは引き続きアクセス可能データは表示できなくなる
ストレージコスト高い (ピクセルデータがデータベース内に存在するため)低い (ピクセルデータが OSS に残るため)

データの耐久性が重要な場合は ST_ImportFrom を使用します。データをコピーせずにその場でクエリしたい場合は ST_CreateRast を使用します。

TIFF データのインポート

  1. TIFF ファイルを OSS バケットにアップロードします。

  2. Raster 型の列を持つテーブルを作成します。

    CREATE TABLE raster_table (
      id      integer,
      format  text,
      rast    raster
    );
  3. どちらかの関数を使用して TIFF をインポートします。

    • ST_ImportFrom を使用する場合 — ピクセルデータは chunk_table に格納されます。

      INSERT INTO raster_table
      SELECT 1, 'TIFF', ST_ImportFrom('chunk_table', 'oss://&lt;access_id&gt;:&lt;secret_key&gt;@[&lt;endpoint&gt;]/&lt;bucket&gt;/path_to/file');
    • ST_CreateRast を使用する場合 — OSS ファイルへのポインターのみが格納されます。

      INSERT INTO raster_table
      SELECT 2, 'TIFF', ST_CreateRast('oss://&lt;access_id&gt;:&lt;secret_key&gt;@[&lt;endpoint&gt;]/&lt;bucket&gt;/path_to/file');
  4. GanosBase UDF (ユーザー定義関数) を使用して、インポートされた Raster オブジェクトをクエリします。

    SELECT
      id,
      ST_Georeference(rast),
      st_extent(rast),
      ST_NumBands(rast),
      ST_SRID(rast),
      st_value(rast, 0, 100, 100),
      st_value(rast, 1, 200, 200)
    FROM raster_table;

    image

HDF5 および NetCDF データのインポート

HDF5 と NetCDF は、地球観測、科学計算、地球科学 (気象学や海洋学など) で使用されます。インポート構文は TIFF と同じです。

  • ST_ImportFrom を使用する場合:

    INSERT INTO raster_table
    SELECT 3, 'NC', ST_ImportFrom('chunk_table', 'oss://<access_id>:<secret_key>@[<endpoint>]/<bucket>/path_to/file');
  • ST_CreateRast を使用する場合:

    INSERT INTO raster_table
    SELECT 4, 'NC', ST_CreateRast('oss://<access_id>:<secret_key>@[<endpoint>]/<bucket>/path_to/file');

サブデータセットを含むファイル

HDF5 および NetCDF ファイルには、名前付きの複数のサブデータセットを含めることができます。ファイルパスにサブデータセット名を追加します。

  • NetCDF:

    INSERT INTO raster_table
    SELECT 5, 'NC', ST_ImportFrom('chunk_table', 'oss://<access_id>:<secret_key>@[<endpoint>]/<bucket>/path_to/file.nc:sub_name');
  • HDF5:

    INSERT INTO raster_table
    SELECT 5, 'HDF5', ST_ImportFrom('chunk_table', 'oss://<access_id>:<secret_key>@[<endpoint>]/<bucket>/path_to/file.hdf5://path/sub_name');

4次元以上のファイル

GanosBase はラスターデータを (w, h, b) チャンクとして格納します。ここで、w は幅、h は高さ、b はバンド数です。4次元以上のファイルの場合、GanosBase が余分なディメンションをバンドにマッピングする方法を認識できるように、chunkdim を明示的に指定します。

NetCDF ファイルの場合、バンド数は x (経度) 軸と y (緯度) 軸を除くすべてのディメンションの積になります。たとえば、lonlattimeisobaric ディメンションを持つファイルには 120 のバンドがあります (これは timeisobaric ディメンションのサイズの積です)。

image
INSERT INTO nc_table
VALUES (
  1,
  ST_ImportFrom(
    'nc_rbt',                         -- チャンクテーブル名
    '/Users/xiaofei/Data/raster/nc_demo.nc',
    '{"chunkdim":"(256,256,120)"}'    -- 256x256 タイル、120 バンド
  )
);

データのバッチインポート

OSS からの一括インポートには、oss2 および psycopg2 ライブラリを使用した Python スクリプトを使用します。スクリプトを実行する前に、OSS Python SDK を初期化してください。詳細については、「初期化」をご参照ください。

import oss2
import psycopg2
import logging

# OSS に接続
auth   = oss2.Auth('AK_ID', 'AK_Secret')
bucket = oss2.Bucket(auth, '***endpoint***', '***bucket_name***')

# データベースに接続
con = psycopg2.connect(
    database="***dataq***",
    user="***dde***",
    options="-c search_path=aster,public",  # スキーマ
    password="******",
    host="*******",
    port="******"
)
cur = con.cursor()

# データインポート用の SQL テンプレート
insert_sql = "INSERT into {raster_table_name}(filename, band_index, raster_obj) VALUES ..."

# OSS から HDF5 ファイル名を収集
for obj in oss2.ObjectIterator(bucket, prefix="..."):
    ff = open("upload.txt", mode='a', encoding='utf-8')
    filename = obj.key.split('/')[-1]
    if filename.find(".hdf5") == -1:
        continue
    else:
        ff.write(filename + '\n')

# ファイルリストを読み取り
with open('upload.txt', 'r') as f:
    fileList = f.read().split('\n')

# 各ファイルをインポート
for file in fileList:
    # 実パラメーターを使用して insert_sql を構築...

    try:
        cur.execute(insert_sql)
        con.commit()
        logging.info(filename + " finished")
    except (Exception, psycopg2.Error) as e:
        logging.info(filename + " error!")
        print(filename + " upload failed\n")
説明

スクリプトを実行する前に、すべてのプレースホルダー値 (*endpoint**bucket_name*AK_IDAK_Secret、およびデータベース接続パラメーター) を実際の認証情報に置き換えてください。