AGEFreighter 2.0.0-rc2をリリースしました

2024年後半にPythonモジュールとして書き始めて、2025年に独立したツールとして実装し直した、Apache AGEにグラフデータを流し込むAGEFreighterですが、PythonをやめてGoで書き直しました(GPT-5.6に書き直させました)。

主な変更点

1.x最後のバージョンである1.0.36からの変更点は以下:

  • 実装言語をPythonからGoへ変更し、単一のクロスプラットフォームバイナリとして配布
  • Python API、CLIオプション、設定形式、デフォルト値を刷新し、1.xとの互換性を廃止
  • validateplanloadresumestatusverifycleanupによるジョブライフサイクルを導入
  • createreplaceappendupsertの4種類のロードモードに対応
  • CSV、PostgreSQL、Neo4j、Azure Cosmos DBを共通のストリーミングパイプラインへ統合
  • チェックポイントを永続化し、中断したマイグレーションの安全な再開に対応
  • 外部ID、エンドポイント、Apache AGE上の物理IDを分離して管理し、ロード間のID安定性を向上
  • ステージングテーブルとバイナリCOPYを利用し、大規模データのロード性能とメモリ効率を改善
  • バッチサイズとメモリ使用量に上限を設け、入力サイズに依存しないメモリ消費を実現
  • CSVのカンマ、タブ、その他の単一文字区切り、および引用・エスケープ設定に対応
  • PostgreSQLのCOPYストリーミングと、再開可能なkeyset paginationに対応
  • Neo4jのラベル、リレーション、プロパティ、エンドポイント構成の自動検出に対応
  • Cosmos DB GremlinのバックエンドドキュメントをNoSQL API経由で自動解釈
  • 頂点数、エッジ数、バイト数、ラベル数を制限できるtrial/sample migrationを追加
  • OpenAIを利用したGremlinからopenCypherへの変換ツールを追加
  • 不正レコードをrejectとして記録し、エラー内容と発生位置を追跡可能に変更
  • 構造化ログとOpenTelemetryによるトレース出力に対応
  • 設定スキーマ、入力値、AGE互換性、シークレット参照をロード前に厳密に検証
  • コネクターごとにcreate → replace → append → upsertのE2Eテストを整備
  • 90%のカバレッジゲート、race test、fuzz test、脆弱性検査をリリース条件に追加
  • CSVからApache AGEへのE2Eロード性能を、1.0.36の54,595 rows/sから118,832 rows/sへ改善(2.18倍)
  • macOS、Linux、Windows向けのリリースアーカイブとSBOM、チェックサム、ビルド来歴を提供
  • macOSバイナリのDeveloper ID署名・notarizationと、WindowsのAuthenticode署名に対応
  • Homebrew Tapからbrew install rioriost/cask/agefreighterでインストール可能な配布方式を追加

廃止した機能

一方で2.0.0で廃止した機能もあります。

  • Pythonパッケージとして公開されていたインポート可能なAPI
  • pipuvによるPythonパッケージとしてのインストール方式
  • 1.xのCLIオプション、JSON設定形式、環境変数、デフォルト値との互換性
  • 接続文字列、パスワード、APIキーなどをコマンドライン引数へ直接指定する方式
  • Flask Web UIでApache AGEのグラフを検索・可視化するviewサブコマンド
  • Cypherクエリを解析して構文構造を出力するparseサブコマンドと公開Cypherパーサー
  • CSVデータをNeo4j、PostgreSQL、Cosmos DB Gremlinへ投入してテスト環境を準備するprepareサブコマンド
  • Fakerと業務ドメイン別パターンを使用する1.xのダミーデータ生成機能
  • ソースコードやURLから複数のGremlin/Cypherクエリを抽出する変換機能
  • CypherをApache AGE用SQLでラップする変換機能
  • Gremlin変換結果をローカルキャッシュへ保存・再利用する機能
  • 変換したクエリをPostgreSQL上で試験実行するconvert --dryrun
  • 移行途中の中間CSVを保存するload --save-temps
  • ロード進行状況を対話的に表示するload --progress
  • 不足しているPythonモジュールを実行時に対話形式でインストールする機能
  • シェル設定ファイルを自動更新する--generate-completion方式

Release Candidate

まだ実環境でのテストが不足しているのでバージョンは2.0.0-rc2としています。制限事項は以下です。

  • macOS版はhomebrewでインストールできません。
  • Windows版はコード署名をしていません。

in English

AGEFreighter, a tool for loading graph data into Apache AGE, started out as a Python module in late 2024 and was reimplemented as a standalone tool in 2025. I've now moved away from Python and rewritten it in Go (or rather, I had GPT-5.6 rewrite it for me).

Main Changes

The main changes from 1.x to 2.0.0 are as follows:

  • Rewritten from Python in Go and distributed as standalone cross-platform binaries
  • Redesigned the Python API, CLI options, configuration format, and defaults, removing compatibility with 1.x
  • Introduced a job lifecycle based on validate, plan, load, resume, status, verify, and cleanup
  • Added four load modes: create, replace, append, and upsert
  • Unified CSV, PostgreSQL, Neo4j, and Azure Cosmos DB under a common streaming pipeline
  • Added persistent checkpoints for safely resuming interrupted migrations
  • Separated external IDs, edge endpoints, and physical Apache AGE IDs to improve identity stability across loads
  • Improved large-scale loading performance and memory efficiency using staging tables and binary COPY
  • Added batch-size and memory limits to keep memory consumption bounded regardless of input size
  • Added support for commas, tabs, and other single-character CSV delimiters, including configurable quoting and escaping
  • Added PostgreSQL COPY streaming and resumable keyset pagination
  • Added automatic discovery of Neo4j labels, relationships, properties, and endpoint combinations
  • Added automatic interpretation of Cosmos DB Gremlin backing documents through the NoSQL API
  • Added trial/sample migrations with limits on vertices, edges, bytes, and labels
  • Added an OpenAI-powered Gremlin-to-openCypher conversion tool
  • Added rejected-record handling with traceable error details and source locations
  • Added structured logging and OpenTelemetry trace export
  • Added strict pre-load validation for configuration schemas, input values, Apache AGE compatibility, and secret references
  • Added create → replace → append → upsert E2E coverage for every connector
  • Added a 90% coverage gate, race tests, fuzz tests, and vulnerability scanning as release requirements
  • Improved end-to-end CSV-to-Apache AGE throughput from 54,595 rows/s in 1.0.36 to 118,832 rows/s in 2.0.0, a 2.18x improvement
  • Added release archives for macOS, Linux, and Windows, including SBOMs, checksums, and build provenance
  • Added Developer ID signing and notarization for macOS binaries and Authenticode signing for Windows binaries
  • Added Homebrew Tap distribution through brew install rioriost/cask/agefreighter

Obsoleted Features

The following features from 1.x were not retained in a backward-compatible form in 2.0.0. Many were replaced by designs that prioritize safety and reproducibility rather than simply being removed.

  • The importable API exposed through the Python package
  • Installation as a Python package through pip or uv
  • Compatibility with the 1.x CLI options, JSON configuration format, environment variables, and defaults
  • Direct command-line arguments for connection strings, passwords, and API keys
  • The view subcommand for querying and visualizing Apache AGE graphs through a Flask Web UI
  • The parse subcommand and public Cypher parser for displaying parsed query structures
  • The prepare subcommand for loading CSV data into Neo4j, PostgreSQL, or Cosmos DB Gremlin test environments
  • The 1.x dummy-data generator based on Faker and predefined business-domain patterns
  • Extraction of multiple Gremlin or Cypher queries from source-code files and URLs
  • Conversion of Cypher queries into Apache AGE SQL wrappers
  • Local caching and reuse of Gremlin conversion results
  • PostgreSQL trial execution through convert --dryrun
  • Preservation of intermediate migration CSV files through load --save-temps
  • Interactive load progress reporting through load --progress
  • Interactive installation of missing Python modules at runtime
  • The --generate-completion workflow that automatically modified shell configuration files

Release Candidate

Since it hasn't yet been sufficiently tested in real-world environments, the current version is 2.0.0-rc2. The known limitations are as follows:

  • The macOS version cannot be installed via Homebrew.
  • The Windows version is not code-signed.