GanosBase は、PolarDB for PostgreSQL (Compatible with Oracle) の空間データベースエンジンです。PolarDB はローカルディスクのない共有ストレージアーキテクチャを採用しているため、標準の PostGIS コマンドラインツール(shp2pgsql、raster2pgsql)を使用してデータをインポートすることはできません。GanosBase は Object Storage Service (OSS) から直接読み取り、代わりにインポート用の SQL 関数を提供します。
インポート方法の選択
開始前にメソッドを選択してください。
| データの型 | 方法 | 最適な用途 |
|---|---|---|
| ベクトル (シェープファイルおよびその他のフォーマット) | FDW | すべてのベクトルデータのインポート。スクリプト化または自動化されたワークフローに推奨 |
| ベクトル (任意のフォーマット) | GIS デスクトップツール (QGIS) | GUI からの単発のインポート |
| ラスター (TIFF、HDF5、NetCDF) | ST_ImportFrom | OSS のソースファイルが削除されてもアクセス可能である必要がある本番データ |
| ラスター (TIFF、HDF5、NetCDF) | ST_CreateRast | データを長期間 OSS に保持し、ソースファイルを自身で管理する探索的クエリ |
PostGIS ツールが PolarDB で機能しない理由
PostGIS は、ベクトルデータとラスターデータをロードするためのコマンドラインツールとして shp2pgsql と raster2pgsql を提供しています。これらのツールが 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
手順
必要な拡張機能をインストールします。
CREATE EXTENSION ganos_spatialref; CREATE EXTENSION ganos_geometry; CREATE EXTENSION ganos_fdw;ST_RegForeignTablesを使用して、シェープファイルを外部テーブルとして登録します。SELECT ST_RegForeignTables('oss://<access_id>:<secret_key>@[<endpoint>]/<bucket>/path_to/poly.shp');プレースホルダーを実際の認証情報とファイルパスに置き換えてください。
プレースホルダー 説明 例 <access_id>Alibaba Cloud AccessKey ID LTAI5tXxx<secret_key>Alibaba Cloud AccessKey Secret xXxXxXx<endpoint>OSS エンドポイント oss-cn-hangzhou.aliyuncs.com<bucket>OSS バケット名 my-geo-bucket外部テーブルが登録されたことを確認します。
SELECT foreign_table_name FROM information_schema.foreign_tables ORDER BY foreign_table_name ASC;結果にテーブル
polyが表示されます。この時点では、polyに対するクエリはオンデマンドで OSS からデータを読み取ります。データはまだデータベースに書き込まれていません。データをデータベースに書き込むには、次を実行します。
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_ImportFrom | ST_CreateRast | |
|---|---|---|
| データベースに格納されるもの | ラスターメタデータ + ピクセルデータ (デフォルトで 256 x 256 ピクセルでチャンク化) | ラスターメタデータのみ (外部イメージへの論理的なマッピング情報) |
| OSS のソースファイルが削除された場合 | データは引き続きアクセス可能 | データは表示できなくなる |
| ストレージコスト | 高い (ピクセルデータがデータベース内に存在するため) | 低い (ピクセルデータが OSS に残るため) |
データの耐久性が重要な場合は ST_ImportFrom を使用します。データをコピーせずにその場でクエリしたい場合は ST_CreateRast を使用します。
TIFF データのインポート
TIFF ファイルを OSS バケットにアップロードします。
Raster 型の列を持つテーブルを作成します。
CREATE TABLE raster_table ( id integer, format text, rast raster );どちらかの関数を使用して TIFF をインポートします。
ST_ImportFromを使用する場合 — ピクセルデータはchunk_tableに格納されます。INSERT INTO raster_table SELECT 1, 'TIFF', ST_ImportFrom('chunk_table', 'oss://<access_id>:<secret_key>@[<endpoint>]/<bucket>/path_to/file');ST_CreateRastを使用する場合 — OSS ファイルへのポインターのみが格納されます。INSERT INTO raster_table SELECT 2, 'TIFF', ST_CreateRast('oss://<access_id>:<secret_key>@[<endpoint>]/<bucket>/path_to/file');
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;
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 (緯度) 軸を除くすべてのディメンションの積になります。たとえば、lon、lat、time、isobaric ディメンションを持つファイルには 120 のバンドがあります (これは time と isobaric ディメンションのサイズの積です)。

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_ID、AK_Secret、およびデータベース接続パラメーター) を実際の認証情報に置き換えてください。