Skip to content

Arrow Flight SQL

Zero-copy columnar access to Elasticsearch over gRPC — for DuckDB, Python, Apache Superset, Grafana, and any Arrow Flight SQL client.

Features

  • gRPC Protocol — High-performance columnar data access over HTTP/2
  • BI Tool Compatible — Works with DBeaver, Superset, Grafana, DataGrip, and any Arrow Flight SQL client
  • Docker Ready — Pre-built Docker images for ES 6, 7, 8, and 9
  • Lazy Streaming — Memory-efficient; only the current batch resides in memory
  • Configurable Batch Size — Via arrow.flight.batch-size
  • Full SQL — DDL + DML + DQL, not just SELECT

Quick Start with Docker

Terminal window
docker run -p 32010:32010 \
-e ES_HOST=elasticsearch \
-e ES_PORT=9200 \
-e ES_USER=elastic \
-e ES_PASSWORD=changeme \
softnetwork/softclient4es8-arrow-flight-sql:latest

Available Docker Images

ElasticsearchDocker Image
ES 6.xsoftnetwork/softclient4es6-arrow-flight-sql:latest
ES 7.xsoftnetwork/softclient4es7-arrow-flight-sql:latest
ES 8.xsoftnetwork/softclient4es8-arrow-flight-sql:latest
ES 9.xsoftnetwork/softclient4es9-arrow-flight-sql:latest

Fat JAR

Terminal window
java -jar softclient4es8-arrow-flight-sql-0.1.5.jar
ElasticsearchArtifact
ES 6.xsoftclient4es6-arrow-flight-sql-0.1.5.jar
ES 7.xsoftclient4es7-arrow-flight-sql-0.1.5.jar
ES 8.xsoftclient4es8-arrow-flight-sql-0.1.5.jar
ES 9.xsoftclient4es9-arrow-flight-sql-0.1.5.jar

Python + DuckDB

import adbc_driver_flightsql.dbapi as flight_sql
import duckdb
conn = flight_sql.connect("grpc://localhost:32010")
cursor = conn.cursor()
cursor.execute("SELECT * FROM ecommerce")
table = cursor.fetch_arrow_table() # zero-copy Arrow table
duckdb.sql("""
SELECT category, SUM(total_price) AS revenue
FROM table
GROUP BY category
ORDER BY revenue DESC
""")

Configuration

arrow.flight {
host = "0.0.0.0" # env: ARROW_HOST
port = 32010 # env: ARROW_PORT
batch-size = 1000 # env: ARROW_BATCH_SIZE
}
elastic.credentials {
host = "localhost" # env: ES_HOST
port = 9200 # env: ES_PORT
user = "elastic" # env: ES_USER
password = "changeme" # env: ES_PASSWORD
}

Arrow Type Mapping

SQL TypeES TypeArrow Type
TINYINTbyteInt(32)
SMALLINTshortInt(32)
INTintegerInt(32)
BIGINTlongInt(64)
REALfloatFloat(SINGLE)
DOUBLEdoubleFloat(DOUBLE)
BOOLEANbooleanBool
DATEdatetimeDate(MILLISECOND)
TIMESTAMPdatetimeTimestamp(MS)
VARCHARtextUtf8
KEYWORDkeywordUtf8
VARBINARYbinaryBinary
STRUCTobjectStruct
GEO_POINTgeo_pointStruct{Float64, Float64}
ARRAY<*>List
ARRAY<STRUCT>nestedList<Struct>

ADBC Driver (In-Process Alternative)

For use cases that don’t need a separate server, the ADBC driver provides in-process columnar access:

val params = new java.util.HashMap[String, AnyRef]()
params.put(AdbcDriver.PARAM_URI.getKey,
"adbc:elastic://localhost:9200?user=elastic&password=changeme")
val db = AdbcDriverManager.getInstance().connect(params, allocator)
val conn = db.connect()
val stmt = conn.createStatement()
stmt.setSqlQuery("SELECT * FROM my_index LIMIT 10")
val result = stmt.executeQuery()

ADBC vs JDBC vs Arrow Flight SQL

FeatureJDBCADBCArrow Flight SQL
Process modelIn-processIn-processSeparate server (gRPC)
Data formatRow-based (ResultSet)Columnar (Arrow)Columnar (Arrow)
ProtocolJDBC APIADBC APIgRPC (HTTP/2)
Use caseJava apps, BI toolsAnalytics, data engineeringMulti-client, networked
SetupJAR on classpathJAR on classpathDocker/server deployment

Live Demos

DuckDB + Python Pipeline

Terminal window
docker compose --profile duckdb up

Apache Superset BI Dashboards

Terminal window
docker compose --profile superset-flight up

Grafana BI Dashboards

Terminal window
docker compose --profile grafana up

License

Arrow Flight SQL is licensed under the Elastic License 2.0 — free to use, not open source.