View Source ReqCH (ReqCH v0.1.1)

A Req plugin for ClickHouse.

By default, ReqCH will use TSV as the default output format. To change that, see the new/2 docs for details.

Summary

Functions

Builds a new %Req.Request{} for ClickHouse requests.

Performs a query against the ClickHouse API.

Functions

new(opts \\ [])

@spec new(Keyword.t()) :: Req.Request.t()

Builds a new %Req.Request{} for ClickHouse requests.

Options

This function can receive any option that Req.new/1 accepts, plus the ones described below.

To set a new endpoint, use the :base_url option from Req. It is by default "http://localhost:8123".

  • :format - Optional. The format of the response. Default is :tsv. This option accepts :tsv, :csv, :json or :explorer as atoms.

    It also accepts all formats described in the https://clickhouse.com/docs/en/interfaces/formats page. Use plain strings for these formats.

    The :explorer format is special, and will build an Explorer dataframe in case the :explorer dependency is installed.

  • :database - Optional. The database to use in the queries. Default is nil.

Examples

After setting a default database, one can make a request directly:

iex> req = ReqCH.new(database: "system")
iex> Req.post!(req, body: "SELECT number + 1 FROM numbers LIMIT 3").body
"1\n2\n3\n"

It's also possible to make a query using Req.get/2:

iex> req = ReqCH.new(database: "system")
iex> Req.get!(req, params: [query: "SELECT number + 1 FROM numbers LIMIT 3"]).body
"1\n2\n3\n"

In case the server needs authentication, it's possible to use Req options for that.

iex> req = ReqCH.new(base_url: "http://example.org:8123", auth: {:basic, "user:pass"})
iex> Req.post!(req, body: "SELECT number FROM system.numbers LIMIT 3").body
"0\n1\n2\n"

query(req, sql_query, sql_query_params \\ [], opts \\ [])

@spec query(
  Req.Request.t(),
  sql_query :: binary(),
  sql_query_params :: map() | Keyword.t(),
  opts :: Keyword.t()
) :: {:ok, Req.Response.t()} | {:error, binary()}

Performs a query against the ClickHouse API.

This version receives a Req.Request.t(), so it won't create a new one from scratch.

By default, it will use the http://localhost:8123 as :base_url. You can change that either providing in your Req request, or in passing down in the options. See new/1 for the options. Like that function, query/4 accepts any option that Req.new/1 accepts.

Examples

Queries can be performed using both Req.get/2 or Req.post/2, but GET is "read-only" and commands like CREATE or INSERT cannot be used with it. For that reason, by default we perform a POST request.

A plain query:

iex> req = ReqCH.new(database: "system")
iex> {:ok, response} = ReqCH.query(req, "SELECT number FROM numbers LIMIT 3")
iex> response.body
"0\n1\n2\n"

With a specific format:

iex> req = ReqCH.new(database: "system")
iex> {:ok, response} = ReqCH.query(req, "SELECT number FROM numbers LIMIT 3", [], [format: :explorer])
iex> response.body
#Explorer.DataFrame<
  Polars[3 x 1]
  number u64 [0, 1, 2]
>

Passing SQL params:

iex> req = ReqCH.new(database: "system")
iex> {:ok, response} = ReqCH.query(req, "SELECT number FROM numbers WHERE number > {num:UInt8} LIMIT 3", [num: 5], [])
iex> response.body
"6\n7\n8\n"

This function can accept Req options, as well as mixing them with ReqCH options:

iex> opts = [base_url: "http://example.org:8123", database: "system", auth: {:basic, "user:pass"}]
iex> {:ok, response} = ReqCH.query(ReqCH.new(), "SELECT number FROM numbers LIMIT 3", [], opts)
iex> response.body
"0\n1\n2\n"

query!(req, sql_query, sql_query_params \\ [], opts \\ [])

@spec query!(
  Req.Request.t(),
  sql_query :: binary(),
  sql_query_params :: map() | Keyword.t(),
  opts :: Keyword.t()
) :: Req.Response.t()

Same as query/4, but raises in case of error.