{{ c.title }}
“{{ c.question }}”
{{ c.story }}
AirMettle Select prepares data in object storage once, then runs parallel SQL queries where the data already lives—built to outperform mainstream query engines without loading a separate data warehouse first.
Mainstream stacks copy, transform, load, and rescan data before returning an answer. AirMettle Select prepares compact metadata once, analyzes the source data in place, and streams only the selected output.
Query CSV, JSON, and JSON Lines directly, including GZIP-compressed CSV and JSON inputs.
{{ f.description }}
We’re extending AirMettle Select to new data formats while keeping the query path direct and warehouse-free.
{{ f.description }}
Keep source data in object storage. AirMettle Select creates compact metadata—typically less than 0.5% of the source size—then analyzes the original data in place and returns only the records your application needs. The exact footprint varies by data type and can be slightly higher for compressed inputs.
Our quickstart walks through a typical workflow and shows how to get started quickly.
AirMettle Select lets you run SQL queries directly against your CSV and JSON blobs in object storage. This quickstart walks through a typical workflow and shows how to get started quickly.
Pick a CSV or JSON blob in your object storage account that you want to query. You need the object URL plus the account name and key.
Use the Python client in this quickstart and install httpx for API calls.
pip install pyamselect httpx
Add your subscription ID, API key, and storage account key as environment variables so credentials stay out of source code.
export AIRMETTLE_SUBSCRIPTION_ID="YOUR_SUBSCRIPTION_ID" export AIRMETTLE_API_KEY="YOUR_API_KEY" export STORAGE_ACCOUNT_KEY="YOUR_STORAGE_ACCOUNT_KEY"
$env:AIRMETTLE_SUBSCRIPTION_ID="YOUR_SUBSCRIPTION_ID" $env:AIRMETTLE_API_KEY="YOUR_API_KEY" $env:STORAGE_ACCOUNT_KEY="YOUR_STORAGE_ACCOUNT_KEY"
set AIRMETTLE_SUBSCRIPTION_ID=YOUR_SUBSCRIPTION_ID set AIRMETTLE_API_KEY=YOUR_API_KEY set STORAGE_ACCOUNT_KEY=YOUR_STORAGE_ACCOUNT_KEY
Link your object storage account to AirMettle Select. This is a one-time step per account.
import os
import httpx
# Include your subscription credentials in the request headers
headers = {
"x-subscription-id": os.getenv("AIRMETTLE_SUBSCRIPTION_ID"),
"x-api-key": os.getenv("AIRMETTLE_API_KEY"),
}
# Create the request body with the storage account name and key
request = {
"storage_account": "yourstorageaccount",
"account_key": os.getenv("STORAGE_ACCOUNT_KEY")
}
response = httpx.post("https://api.airmettle.com/api/v1/buckets", json=request, headers=headers)
print(response.status_code, response.text)
A 201 Created response means the account was linked successfully.
Before querying a blob, AirMettle Select generates a small sidecar metadata file. These sidecars live in a hidden directory alongside your data and enable parallel high-performance reads.
You can generate a sidecar on demand. The original blob is never modified, and you can delete and regenerate the sidecar at any time.
import os
import httpx
# Specify the blob URL and your subscription credentials in the request body
request = {
"subscription_id": os.getenv("AIRMETTLE_SUBSCRIPTION_ID"),
"api_key": os.getenv("AIRMETTLE_API_KEY"),
"blob_url": "https://yourstore.blob.core.windows.net/container/yourblob.csv",
"account_key": os.getenv("STORAGE_ACCOUNT_KEY")
}
response = httpx.post("https://api.airmettle.com/v1/prepare", json=request)
print(response.status_code, response.text)
A 200 OK response means the metadata object is ready and queryable. A 202 Accepted response means generation is asynchronous and includes a status_url for polling.
In step 5, you prepared a blob using its full blob_url. In this step, identify the same blob by storage_account, container, and blob. The response is a stream of selected rows in the requested format.
import os
from pyamselect import AMSelectClient, SelectRequest, CSVInputOptions, CSVOutputOptions
# Specify which blob to query, the SQL, and input/output options
request = SelectRequest(
subscription_id=os.getenv("AIRMETTLE_SUBSCRIPTION_ID"),
api_key=os.getenv("AIRMETTLE_API_KEY"),
storage_account="yourstorageaccount",
container="yourcontainer",
blob="yourblob.csv",
expression="SELECT * FROM s3object", # Your SQL query
input_options=CSVInputOptions(csv_header_config="use",csv_field_delimiter=","), # input as CSV
output_options=CSVOutputOptions(), # output as CSV
)
# Create the client to connect to AirMettle Select
with AMSelectClient("api.airmettle.com/query", 8443) as client:
# Run the query and collect the results as a string
result = client.select_to_string(request)
print(result)
# Alternatively, write results directly to a file
# client.select_to_file(request, "output.csv")
# Or write results to a binary stream, such as a BytesIO object
# client.select_to_stream(request, stream)
Start by linking one storage account, prepare metadata for a few sample blobs, and run your first query.
AirMettle Select runs SQL directly against objects in object storage. The current query surface supports CSV, JSON, and GZIP-compressed variants of these formats.
When creating a request, set input options for parsing and output options for the stream format returned to your application.
from pyamselect import SelectRequest, CSVInputOptions, CSVOutputOptions
request = SelectRequest(
...
expression="SELECT * FROM s3object",
input_options=CSVInputOptions(
csv_header_config="use",
csv_field_delimiter=","
),
output_options=CSVOutputOptions(),
)
AirMettle Select runs familiar SQL against CSV and JSON objects in object storage. Built on the same SQL surface as Amazon S3 Select, it provides a fast way to filter, project, and aggregate data in place.
Sidecar metadata is generated once per blob so subsequent queries run in parallel and return results quickly.
Aggregate functions ignore MISSING values and return a single summary row.
AirMettle Select implements a focused SQL subset optimized for object storage. The core statement structure is shown below. Currently, explicit JOINs are not supported.
SELECT [projections] FROM [relation] WHERE [condition] LIMIT [number]
Project specific columns, expressions, or function results and use aliases with AS.
SELECT column1, column2 SELECT *
Query a single object relation.
FROM S3Object
Filter rows with boolean expressions.
WHERE amount > 100 WHERE status = 'active' AND region IS NOT MISSING WHERE regexp_contains(email, '@company\\.com')
Cap returned records for sampling and preview.
LIMIT 100
Reference CSV columns by position (_1, _2, and so on) or by header name when headers are present. Header names are case-insensitive unless wrapped in double quotes.
SELECT _1, _3 FROM S3Object WHERE _2 > 50 SELECT email FROM S3Object WHERE status = 'active'
Use dot notation for nested fields and zero-based indexes for arrays. Start from S3Object[*] when JSON is treated as an array of root values.
SELECT s.projects[0].project_name FROM S3Object s SELECT s."CAST", s."Name" FROM S3Object s
Explore measured AirMettle Select performance across operational investigations and the ClickBench query suite.
Three queries across a 332.7 million-event source show how AirMettle Select handles an urgent filter, a day-long investigation, and a complete 90-day history without loading the data into a warehouse.
“{{ c.question }}”
{{ c.story }}
See the one-time preparation total and ongoing metadata storage cost for the complete source.
Monthly storage is estimated using East US 2 Hot LRS at $0.0184/GB-month. Actual storage costs vary.
Compare AirMettle Select and Synapse across the same ClickBench query suite using the recorded 6.6% CSV results.
AirMettle Select and Synapse measurements will be published side by side with the workload and test details.
Keep source data in object storage and limit each query to the storage scope your application is allowed to use.
{{ s.d }}
The essentials for evaluating AirMettle Select, from supported data to deployment and pricing.