View Source Snowpack (Snowpack v0.7.5)
Snowflake driver for Elixir.
features
Features
- Automatic decoding and encoding of Elixir values to and from Snowflake's ODBC driver formats
- Supports transactions, prepared queries, pooling and more via DBConnection
- Supports Snowflake ODBC Drivers 2.24.7+
todo
TODO
- Support streaming via DBConnection
usage
Usage
Add :snowpack
to your dependencies:
def deps() do
[
{:snowpack, "~> 0.6.0"}
]
end
Make sure you are using the latest version!
opts = [
connection: [
role: "DEV",
warehouse: System.get_env("SNOWFLAKE_WH"),
uid: System.get_env("SNOWFLAKE_UID"),
pwd: System.get_env("SNOWFLAKE_PWD")
]
]
{:ok, pid} = Snowpack.start_link(opts)
Snowpack.query!(pid, "select current_user()")
Snowpack.query(pid, "SELECT * FROM data")
{:ok,
%Snowpack.Result{
columns: ["id", "title"],
num_rows: 3,
rows: [[1, "Data 1"], [2, "Data 2"], [3, "Data 3"]]
}}
It's recommended to start Snowpack under a supervision tree:
defmodule MyApp.Application do
use Application
def start(_type, _args) do
children = [
{Snowpack, uid: "snowflake-uid", name: :snowpack}
]
opts = [strategy: :one_for_one, name: MyApp.Supervisor]
Supervisor.start_link(children, opts)
end
end
and then we can refer to it by its :name
:
Snowpack.query!(:snowpack, "SELECT NOW()").rows
[[~N[2018-12-28 13:42:31]]]
data-representation
Data representation
Snowflake ODBC Elixir
----- ------
NULL nil
bool true | false
int 42
float 42.0
decimal 42.0 # (1)
date ~D[2013-10-12]
time ~T[00:37:14]
datetime ~N[2013-10-12 00:37:14] # (2)
timestamp ~U[2013-10-12 00:37:14Z] # (2)
char "é"
text "snowpack"
binary <<1, 2, 3>>
bit <<1::size(1), 0::size(1)>>
array [1, 2, 3]
object %{key: "value"}
Notes:
See Decimal
Datetime fields are represented as
NaiveDateTime
, however a UTCDateTime
can be used for encoding as well.
Link to this section Summary
Functions
Returns a supervisor child specification for a DBConnection pool.
Closes a prepared query.
Executes a prepared query.
Executes a prepared query.
Prepares a query.
Prepares a query to be executed later.
Prepares and executes a query in a single step.
Prepares and executes a query in a single step.
Runs a query.
Runs a query.
Starts the connection process and connects to Snowflake.
Return the transaction status of a connection.
Link to this section Types
@type conn() :: DBConnection.conn()
@type option() :: DBConnection.option()
@type query_option() :: {:parse_results, boolean()} | DBConnection.option()
@type snowflake_conn_option() :: {:dsn, String.t()} | {:driver, String.t()} | {:server, String.t()} | {:role, String.t()} | {:warehouse, String.t()} | {:database, String.t()} | {:schema, String.t()} | {:uid, String.t()} | {:pwd, String.t()} | {:authenticator, String.t()} | {:token, String.t()} | {:priv_key_file, String.t()} | {:priv_key_file_pwd, String.t()}
@type start_option() :: {:connection, snowflake_conn_option()} | DBConnection.start_option()
Link to this section Functions
@spec child_spec([start_option()]) :: :supervisor.child_spec()
Returns a supervisor child specification for a DBConnection pool.
@spec close(conn(), Snowpack.Query.t(), [option()]) :: :ok | {:error, Exception.t()}
Closes a prepared query.
Returns :ok
on success, or raises an exception if there was an error.
options
Options
Options are passed to DBConnection.close/3
, see it's documentation for
all available options.
@spec execute!(conn(), Snowpack.Query.t(), list(), keyword()) :: Snowpack.Result.t()
Executes a prepared query.
Returns %Snowpack.Result{}
on success, or raises an exception if there was an error.
See: execute/4
.
@spec execute(conn(), Snowpack.Query.t(), list(), [query_option()]) :: {:ok, Snowpack.Query.t(), Snowpack.Result.t()} | {:error, Exception.t()}
Executes a prepared query.
options
Options
Options are passed to DBConnection.execute/4
, see it's documentation for
all available options.
examples
Examples
iex> {:ok, query} = Snowpack.prepare(conn, "", "SELECT ? * ?")
iex> {:ok, %Snowpack.Result{rows: [row]}} = Snowpack.execute(conn, query, [2, 3])
iex> row
[6]
@spec prepare!(conn(), iodata(), iodata(), [query_option()]) :: Snowpack.Query.t()
Prepares a query.
Returns %Snowpack.Query{}
on success, or raises an exception if there was an error.
See prepare/4
.
@spec prepare(conn(), iodata(), iodata(), [query_option()]) :: {:ok, Snowpack.Query.t()} | {:error, Exception.t()}
Prepares a query to be executed later.
To execute the query, call execute/4
. To close the query, call close/3
.
If a name is given, the name must be unique per query, as the name is cached
but the statement isn't. If a new statement is given to an old name, the old
statement will be the one effectively used.
options
Options
Options are passed to DBConnection.prepare/3
, see it's documentation for
all available options.
additional-options
Additional Options
:parse_results
- Wether or not to do type parsing on the results. Requires execution to be performed inside a transaction and an extraDESCRIBE RESULT
to get the types of the columns in the result. Only important forSELECT
queries. Default true.
examples
Examples
iex> {:ok, query} = Snowpack.prepare(conn, "", "SELECT ? * ?")
iex> {:ok, %Snowpack.Result{rows: [row]}} = Snowpack.execute(conn, query, [2, 3])
iex> row
[6]
@spec prepare_execute!(conn(), iodata(), iodata(), list(), [query_option()]) :: {Snowpack.Query.t(), Snowpack.Result.t()}
Prepares and executes a query in a single step.
Returns {%Snowpack.Query{}, %Snowpack.Result{}}
on success, or raises an exception if there was
an error.
See: prepare_execute/5
.
@spec prepare_execute(conn(), iodata(), iodata(), list(), keyword()) :: {:ok, Snowpack.Query.t(), Snowpack.Result.t()} | {:error, Exception.t()}
Prepares and executes a query in a single step.
multiple-results
Multiple results
If a query returns multiple results (e.g. it's calling a procedure that returns multiple results)
an error is raised. If a query may return multiple results it's recommended to use stream/4
instead.
options
Options
Options are passed to DBConnection.prepare_execute/4
, see it's documentation for
all available options.
additional-options
Additional Options
:parse_results
- Wether or not to do type parsing on the results. Requires execution to be performed inside a transaction and an extraDESCRIBE RESULT
to get the types of the columns in the result. Only important forSELECT
queries. Default true.
examples
Examples
iex> {:ok, _query, %Snowpack.Result{rows: [row]}} = Snowpack.prepare_execute(conn, "", "SELECT ? * ?", [2, 3])
iex> row
[6]
@spec query!(conn(), iodata(), list(), [query_option()]) :: Snowpack.Result.t()
Runs a query.
Returns %Snowpack.Result{}
on success, or raises an exception if there was an error.
See query/4
.
@spec query(conn(), iodata(), list(), [query_option()]) :: {:ok, Snowpack.Result.t()} | {:error, Exception.t()}
Runs a query.
options
Options
Options are passed to DBConnection.prepare/3
, see it's documentation for
all available options.
additional-options
Additional Options
:parse_results
- Wether or not to do type parsing on the results. Requires execution to be performed inside a transaction and an extraDESCRIBE RESULT
to get the types of the columns in the result. Only important forSELECT
queries. Default true.
examples
Examples
iex> Snowpack.query(conn, "SELECT * FROM RECORDS")
{:ok, %Snowpack.Result{}}
iex> Snowpack.query(conn, "INSERT INTO RECORDS (ROW1, ROW2) VALUES(?, ?)", [1, 2], parse_results: false)
@spec start_link([start_option()]) :: {:ok, pid()} | {:error, Snowpack.Error.t()}
Starts the connection process and connects to Snowflake.
options
Options
snowflake-connection-options
Snowflake Connection Options
See: https://docs.snowflake.com/en/user-guide/odbc-parameters.html#required-connection-parameters
:connection
:dsn
- Specifies the name of your DSN:driver
- Snowflake ODBC driver path:server
- Specifies the hostname for your account:role
- Specifies the default role to use for sessions initiated by the driver:warehouse
- Specifies the default warehouse to use for sessions initiated by the driver:database
- Specifies the default database to use for sessions initiated by the driver:schema
- Specifies the default schema to use for sessions initiated by the driver (default:public
):uid
- Specifies the login name of the Snowflake user to authenticate:pwd
- A password is required to connect to Snowflake:authenticator
- Specifies the authenticator to use for verifying user login credentials:token
- Specifies the token to use for token based authentication:priv_key_file
- Specifies the local path to the private key file
dbconnection-options
DBConnection Options
The given options are passed down to DBConnection, some of the most commonly used ones are documented below:
:after_connect
- A function to run after the connection has been established, either a 1-arity fun, a{module, function, args}
tuple, ornil
(default:nil
):pool
- The pool module to use, defaults to built-in pool provided by DBconnection:pool_size
- The size of the pool
See DBConnection.start_link/2
for more information and a full list of available options.
examples
Examples
Start connection using basic User / Pass configuration:
iex> {:ok, pid} = Snowpack.start_link(connection: [server: "account-id.snowflakecomputing.com", uid: "USER", pwd: "PASS"])
{:ok, #PID<0.69.0>}
Start connection using DNS configuration:
iex> {:ok, pid} = Snowpack.start_link(connection: [dsn: "snowflake"])
{:ok, #PID<0.69.0>}
Run a query after connection has been established:
iex> {:ok, pid} = Snowpack.start_link(connection: [dsn: "snowflake"], after_connect: &Snowpack.query!(&1, "SET time_zone = '+00:00'"))
{:ok, #PID<0.69.0>}
@spec status(conn(), opts :: Keyword.t()) :: DBConnection.status()
Return the transaction status of a connection.