Getting Started with Pillar
View SourceThis guide will help you get up and running with Pillar, the Elixir client for ClickHouse.
Installation
Add pillar
to your list of dependencies in mix.exs
:
def deps do
[
{:pillar, "~> 0.39.0"}
]
end
Then run:
mix deps.get
Basic Configuration
Direct Connection
The simplest way to use Pillar is with a direct connection:
# Create a connection to your ClickHouse server
conn = Pillar.Connection.new("http://user:password@localhost:8123/database")
The connection URL follows this format:
http://[username:password@]host[:port]/database
Where:
username
andpassword
are your ClickHouse credentials (default: default/empty)host
is the ClickHouse server hostname or IPport
is the HTTP port (default: 8123)database
is the database name
Connection Options
You can provide additional options when creating a connection:
conn = Pillar.Connection.new(
"http://user:password@localhost:8123/database",
%{
timeout: 30_000, # Connection timeout in milliseconds
max_execution_time: 60, # Maximum query execution time in seconds
database: "analytics" # Override database in URL
}
)
Basic Operations
Running Queries
# Simple query
{:ok, result} = Pillar.query(conn, "SELECT 1")
# Parameterized query
{:ok, users} = Pillar.select(
conn,
"SELECT * FROM users WHERE age > {min_age} LIMIT {limit}",
%{min_age: 21, limit: 100}
)
Inserting Data
# Insert with parameters
{:ok, _} = Pillar.insert(
conn,
"INSERT INTO events (user_id, event_type, created_at) VALUES ({user_id}, {event_type}, {created_at})",
%{user_id: 123, event_type: "login", created_at: DateTime.utc_now()}
)
# Insert a record using a map
{:ok, _} = Pillar.insert_to_table(
conn,
"users",
%{
id: 456,
name: "John Doe",
email: "john@example.com",
created_at: DateTime.utc_now()
}
)
# Insert multiple records
{:ok, _} = Pillar.insert_to_table(
conn,
"users",
[
%{id: 1, name: "Alice", email: "alice@example.com"},
%{id: 2, name: "Bob", email: "bob@example.com"},
%{id: 3, name: "Charlie", email: "charlie@example.com"}
]
)
Understanding Responses
Most Pillar functions return one of these response patterns:
{:ok, result} # Success with result data
{:error, reason} # Error with reason
For example:
case Pillar.select(conn, "SELECT * FROM users LIMIT 10") do
{:ok, users} ->
# Do something with the users list
Enum.each(users, &IO.inspect/1)
{:error, error} ->
# Handle the error
Logger.error("Query failed: #{inspect(error)}")
end
Next Steps
Now that you have a basic understanding of how to use Pillar, you might want to explore:
- Connection Pool for managing multiple connections
- Migrations for managing your ClickHouse schema
- Bulk Insert Strategies for efficiently loading data