Querying#

Subgrounds provides 3 main ways to query data, which provide different data structures and typing:

Function

Return Type

Description

query()

str | int | float | bool | list | tuple | None

The shape of the queried data will determine the shape of the returned data (e.g. whether you query a single entity, list of entities)

query_json()

dict

For subgraphs, this can include generated id keys for each generated sub-query.

query_df()

DataFrame | list[DataFrame]

Flattened based on the schema of the API from query_json(), mimicking an SQL JOIN operation. If flattening isn't possible, multiple Dataframes will be returned (like when querying a nested list).

Tip

query_df() will likely the best choice for you!

Quick Example#

The following code blocks present a comparison between all methods using the aave-v2 market data:

Setup for the following examples of the query methods using the Aave V2 data from Ethereum#
from subgrounds import Subgrounds

sg = Subgrounds()
aave_v2 = sg.load_subgraph(
    "https://api.thegraph.com/subgraphs/name/messari/aave-v2-ethereum")

aave_markets = aave_v2.Query.markets(
    first=3,
    orderBy=aave_v2.Market.totalValueLockedUSD,
    orderDirection="desc",
    where=[
        aave_v2.Market.createdBlockNumber > 14720000
    ]
)
A list of names and a matching list TVL values gets returned#
sg.query([
    aave_markets.name,
    aave_markets.totalValueLockedUSD,
])
A more complex JSON data structure gets returned#
sg.query_json([
    aave_markets.name,
    aave_markets.totalValueLockedUSD,
])
✨ A simple DataFrame gets returned#
sg.query_df([
    aave_markets.name,
    aave_markets.totalValueLockedUSD,
])

Naming your columns

query_df() can also take an optional parameter columns, which let you name the column for each field path!

sg.query_df(
    [aave_markets.name, aave_markets.totalValueLockedUSD],
    columns=["Name", "TVL (USD)"],
)

Tip New in version 1.7.0

The Graph provides a default server timeout of 30s so we've chosen this as our default for subgrounds. However, if you are using a custom or self-hosted indexer, you might want to adjust this timeout value. You can do so via the timeout constructor param.

sg = Subgrounds(timeout=60)