Low-level wrapper around the bean-query command-line tool.
Query is the only place that shells out to bean-query, mirroring how
Beancount.Checker wraps bean-check. It runs a BQL query against a ledger
with CSV output and parses the result into a neutral
Beancount.Query.Result.
The path to bean-query is configurable:
config :beancount_ex, bean_query_path: "bean-query"
Summary
Functions
Whether the configured bean-query executable is available on this machine.
Return the configured path to the bean-query executable.
Parse RFC-4180-style CSV text into {columns, rows}.
Run bql against a .bean file on disk.
Run bql against ledger text, writing it to a temporary file first.
Functions
@spec available?() :: boolean()
Whether the configured bean-query executable is available on this machine.
Examples
iex> is_boolean(Beancount.Query.available?())
true
@spec bean_query_path() :: String.t()
Return the configured path to the bean-query executable.
Examples
iex> is_binary(Beancount.Query.bean_query_path())
true
Parse RFC-4180-style CSV text into {columns, rows}.
The first non-empty line is treated as the header. Empty input yields
{[], []}. Quoted fields may contain embedded newlines.
Examples
iex> Beancount.Query.parse_csv("account,balance\nAssets:Bank,100 USD\n")
{["account", "balance"], [["Assets:Bank", "100 USD"]]}
iex> Beancount.Query.parse_csv("")
{[], []}
@spec query_file(Path.t(), binary()) :: {:ok, Beancount.Query.Result.t()} | {:error, Beancount.Result.t()}
Run bql against a .bean file on disk.
Raises Beancount.Query.NotInstalledError if bean-query is not available.
Examples
path = Path.join(System.tmp_dir!(), "query_file_example.bean")
File.write!(path, "2026-01-01 open Assets:Bank USD\n")
if Beancount.Query.available?() do
{:ok, _} = Beancount.Query.query_file(path, "SELECT account GROUP BY account")
end
@spec query_text(binary(), binary()) :: {:ok, Beancount.Query.Result.t()} | {:error, Beancount.Result.t()}
Run bql against ledger text, writing it to a temporary file first.
Examples
Requires bean-query on PATH:
text = "2026-01-01 open Assets:Bank USD\n"
if Beancount.Query.available?() do
{:ok, %Beancount.Query.Result{}} =
Beancount.Query.query_text(text, "SELECT account GROUP BY account")
end