Klickhouse is a pure Rust SDK for working with Clickhouse

Related tags

Database klickhouse
Overview

Klickhouse

Klickhouse is a pure Rust SDK for working with Clickhouse with the native protocol in async environments with minimal boilerplate and maximal performance.

Example Usage

See example usage.

Unsupported Features

  • Clickhouse Enum8 and Enum16 types -- use LowCardinality instead.

Credit

klickhouse_derive was made by copy/paste/simplify of serde_derive to get maximal functionality and performance at lowest time-cost. In a prototype, serde was directly used, but this was abandoned due to lock-in of serde's data model.

Comments
  • Consider supporting rust_decimal for Decimal{32, 64}

    Consider supporting rust_decimal for Decimal{32, 64}

    Currently especially when inserting data, there doesn't appear to be a good way to create a decimal number using this library? Perhaps we could use rust_decimal here as a feature?

    opened by Swoorup 2
  • How to insert custom data which is hard to pre-defined

    How to insert custom data which is hard to pre-defined

    I'm writing a kafka consumer, it consumes message and insert those message into clickhouse according to message's meta info, like:

    {
      "table": "ch_table_1",
      "data": [
        {"col_name": "foo", "type": "uint32", "val": "3"},
        {"col_name": "bar", "type": "string", "val": "hello"}
        //...
      ]
    }
    

    How do I construct the Row to insert? Didn't find any docs about this

    opened by caibirdme 2
  • Error when requesting for a lot of Array data on a single query.

    Error when requesting for a lot of Array data on a single query.

    When performing a select query on a database with big arrays, the channel created to receive the query results get a capacity overflow. This is so because it eventually fails to read correctly the size of the array. It looks like the pointer is not correctly placed when reading arrays. (Fixing the size for a quick test returns the array values with 0's at the beginning, so all the values are shifted). @Protryon

    opened by jfontanet 2
  • [bug] read_binary read twice

    [bug] read_binary read twice

    There are read_exact calls at Line#58 and Line#61.

    https://github.com/Protryon/klickhouse/blob/ce78975828b85c2955ed8889a8e8f5b889d76a63/klickhouse/src/io.rs#L47-L65

    opened by alanhe 1
  • Nullable<Bool> not being treated as Option<bool>

    Nullable not being treated as Option

    /*
    create table trade_event (
        symbol LowCardinality(FixedString(16)),
        exchange_id LowCardinality(String),
        trade_id UInt64,
        ts DateTime64(6),
        received_ts DateTime64(6),
        is_buyer_maker Nullable(Bool),
        price Decimal64(6),
        size Decimal64(6)
    ) 
    engine = MergeTree()
    partition by ts
    order by (symbol, exchange_id, ts);
    */
    
    #[derive(Row, Debug, Default)]
    pub struct TradeEvent {
      symbol: String,
      exchange_id: String,
      trade_id: u64,
      ts: DateTime64<6>,
      received_ts: DateTime64<6>,
      is_buyer_maker: Option<bool>,
      price: FixedPoint64<6>,
      size: FixedPoint64<6>,
    }
    
    

    Reading the row this currently gives the following error:

    thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: DeserializeErrorWithColumn("is_buyer_maker", "unexpected type: Int8")',
    

    EDIT: Looks like not just option, its without as well.

    opened by Swoorup 1
  • Default expression does not evaluate with native inserts

    Default expression does not evaluate with native inserts

    Hey, thanks for working on this crate. I've run into an issue where DEFAULT columns are not getting set properly.

    To reproduce the issue, you can follow these steps:

    1. Create test table
    create table test (id UInt32, id_bump DEFAULT id+1) ENGINE = MergeTree() ORDER BY id;
    
    1. Insert values
    // main.rs
    
    #[derive(Row, Debug, Default)]
    pub struct Test {
        id: u32,
    }
    
    // glue code
    
    #[tokio::main]
    async fn main() {
        // init client
        
        let row = Test {
            id: 1,
        };
        
        client
            .insert_native_block("INSERT INTO test FORMAT native", vec![row])
            .await
            .unwrap();
     }
    

    On querying the table, I see that the default expression (id+1) set for column id_bump is not being honored. Any idea why this may be?

    Observed:

    SELECT *
    FROM test
    
    ┌─id─┬─id_bump─┐
    │  1 │       0 │
    └────┴─────────┘
    

    Expected:

    SELECT *
    FROM test
    
    ┌─id─┬─id_bump─┐
    │  1 │       2 │
    └────┴─────────┘
    

    cc: @tekjar

    opened by mnpw 1
  • error handling

    error handling

    Dude, the error handling on this is terrible. Most errors are not returned, but simply logged. And there is no trace about the path it took to reach that error.

    opened by petar-dambovaliev 1
  • Execute large query failed with error:unexpected end of file

    Execute large query failed with error:unexpected end of file

    I submit a SQL query that was expected to return 7 million rows, but the client threw an error : " ERROR [tokio-runtime-worker] [/Users/bmmcq/.cargo/registry/src/github.com-1ecc6299db9ec823/klickhouse-0.2.1/src/client.rs:168] clickhouse client failed: unexpected end of file " and exit with the wrong number of rows.

    There is the code:

    #[tokio::main]
    async fn main() {
        pegasus_common::logs::init_log();
        let mut opt = ClientOptions::default();
        opt.default_database = "mydb".to_owned();
        let client = Client::connect("myip:9000", opt)
            .await
            .unwrap();
        let query = "select * from mytable where my_id in (8,10,11,13,15,17,19,20,22,24,26,28,30)";
        let start = Instant::now();
        let mut all_rows = client
            .query_raw(query)
            .await
            .unwrap();
    
        let mut count = 0u64;
        while let Some(row) = all_rows.next().await {
            println!("row {}", row.rows);
            count += row.rows;
        }
        println!("total received {} records, used {:?};", count, start.elapsed());
    }
    
    opened by bmmcq 1
  • [Q] Might it possible to rename columns?

    [Q] Might it possible to rename columns?

    Like that

    #[derive(Row, Debug, Default)]
    pub struct MyUserData {
       #[serde(rename = "Id")]
       id: Uuid,
       #[serde(rename = "UserData")]
       user_data: String,
       #[serde(rename = "CreatedAt")]
       created_at: DateTime,
    }
    
    opened by ablearthy 1
  • Bug:the From Trait Wront Impl for kilickhouse::DateTime and Chrono::DateTime

    Bug:the From Trait Wront Impl for kilickhouse::DateTime and Chrono::DateTime

    hello,my bro.i'm a beginner on Rust,so maybe something i say sounds childrens,on your eyes..

    Problem

    https://stackoverflow.com/questions/61179070/rust-chrono-parse-date-string-parseerrornotenough-and-parseerrortooshort I want to conver a standard datatime "2022-04-22 00:00:00" convert to the klickhouse::DateTime. it should be okay,but failed. During finding the bug step by step, I write a test for this.

        #[test]
        fn test_consistency_with_convert_for_str() {
            let test_date = "2022-04-22 00:00:00";
    
            let dt = chrono::NaiveDateTime::parse_from_str(test_date, "%Y-%m-%d %H:%M:%S").unwrap();
    
            let chrono_date =
                chrono::DateTime::<Tz>::from_utc(dt, chrono_tz::UTC.offset_from_utc_datetime(&dt));
    
            let date = DateTime(UTC, dt.timestamp() as u32);
    
            let new_chrono_date: chrono::DateTime<Tz> = date.into();
    
            assert_eq!(new_chrono_date, chrono_date);
        }
    

    also,there have two test before in the file src/values/date.rs...i confrim the old impl for From cant not pass this test_case. @Protryon

    opened by csh0101 0
  • Columnar derived types

    Columnar derived types

    At the moment we have klickhouse::Row derivable trait and klickhouse::Block raw columnar storage. It would be ideal to have a derivable, easy-to-use klickhouse::Columnar derivable trait akin to klickhouse::Row but with the superior performance of actually being columnar.

    No idea when I'll have time/motivation to implement this, but it's been on my mind.

    enhancement 
    opened by Protryon 0
Releases(v0.8.2)
  • v0.8.2(Dec 7, 2022)

  • v0.8.1(Dec 7, 2022)

  • v0.8.0(Dec 7, 2022)

    Notable Changes:

    • Added derive field flag: #[klickhouse(nested)] for automatic nested structure composition. The target type must be ::std::vec::Vec<T> where T: Row. No other containers are supported at this time.
    • Added rust_decimal feature flag (non-default). rust_decimal::Decimal implements klickhouse::ToSql and klickhouse::FromSql in this release.
    • ToSql and Row::serialize_row now pass in optional type hints. This is currently only used for rust_decimal integration, but some more serialization coercions may be added in the future. This is an API breakage (hence minor version bump).
    Source code(tar.gz)
    Source code(zip)
Owner
Max Bruce
General enthusiast of everything code.
Max Bruce
🧰 The Rust SQL Toolkit. An async, pure Rust SQL crate featuring compile-time checked queries without a DSL. Supports PostgreSQL, MySQL, SQLite, and MSSQL.

SQLx ?? The Rust SQL Toolkit Install | Usage | Docs Built with ❤️ by The LaunchBadge team SQLx is an async, pure Rust† SQL crate featuring compile-tim

launchbadge 7.6k Dec 31, 2022
Pure Rust library for Apache ZooKeeper built on MIO

rust-zookeeper Zookeeper client written 100% in Rust This library is intended to be equivalent with the official (low-level) ZooKeeper client which sh

Nándor István Krácser 168 Dec 25, 2022
AgateDB is an embeddable, persistent and fast key-value (KV) database written in pure Rust

AgateDB is an embeddable, persistent and fast key-value (KV) database written in pure Rust. It is designed as an experimental engine for the TiKV project, and will bring aggressive optimizations for TiKV specifically.

TiKV Project 535 Jan 9, 2023
Pure rust embeddable key-value store database.

MHdb is a pure Rust database implementation, based on dbm. See crate documentation. Changelog v1.0.3 Update Cargo.toml v1.0.2 Update Cargo.toml v1.0.1

Magnus Hirth 7 Dec 10, 2022
A pure Rust database implementation using an append-only B-Tree file format.

nebari nebari - noun - the surface roots that flare out from the base of a bonsai tree Warning: This crate is early in development. The format of the

Khonsu Labs 194 Jan 3, 2023
A pure-Rust library to interact with systemd DBus services

A pure-Rust library to interact with systemd DBus services

Luca Bruno 10 Nov 23, 2022
Pure Rust implementation of Arbitrum sequencer feed reader with built-in transaction decoding and MEV features

Sequencer-Client (WIP ?? ) Pure Rust implementation of Arbitrum sequencer feed reader with built-in transaction decoding and MEV features Design Goal

duoxehyon 11 Apr 23, 2023
Lightweight async Redis client with connection pooling written in pure Rust and 100% memory safe

redi-rs (or redirs) redi-rs is a Lightweight Redis client with connection pooling written in Rust and 100% memory safe redi-rs is a Redis client writt

Oğuz Türkay 4 May 20, 2023
Redis re-implemented in Rust.

rsedis Redis re-implemented in Rust. Why? To learn Rust. Use Cases rsedis does not rely on UNIX-specific features. Windows users can run it as a repla

Sebastian Waisbrot 1.6k Jan 6, 2023
A generic connection pool for Rust

r2d2 A generic connection pool for Rust. Documentation Opening a new database connection every time one is needed is both inefficient and can lead to

Steven Fackler 1.2k Jan 8, 2023
An ArangoDB driver for Rust

Rincon Rincon is an ArangoDB driver for Rust. It enables low level access to ArangoDB in a typesafe and Rust idiomatic manner. The name Rincon is deri

Innoave 35 Mar 21, 2021
Cassandra DB native client written in Rust language. Find 1.x versions on https://github.com/AlexPikalov/cdrs/tree/v.1.x Looking for an async version? - Check WIP https://github.com/AlexPikalov/cdrs-async

CDRS CDRS is looking for maintainers CDRS is Apache Cassandra driver written in pure Rust. ?? Looking for an async version? async-std https://github.c

Alex Pikalov 338 Jan 1, 2023
Cassandra (CQL) driver for Rust, using the DataStax C/C++ driver under the covers.

cassandra-cpp This is a maintained Rust project that exposes the DataStax cpp driver at https://github.com/datastax/cpp-driver/ in a somewhat-sane cra

null 93 Jan 7, 2023
CouchDB client-side library for the Rust programming language

Chill Chill is a client-side CouchDB library for the Rust programming language, available on crates.io. It targets Rust Stable. Chill's three chief de

null 35 Jun 26, 2022
Sofa - CouchDB for Rust

Sofa - CouchDB for Rust Documentation Here: http://docs.rs/sofa Installation [dependencies] sofa = "0.6" Description This crate is an interface to Cou

66 Origin 40 Feb 11, 2022
⚡🦀 🧨 make your rust types fit DynamoDB and visa versa

?? ?? dynomite dynomite makes DynamoDB fit your types (and visa versa) Overview Goals ⚡ make writing dynamodb applications in rust a productive experi

Doug Tangren 197 Dec 15, 2022
A Rust client for the ElasticSearch REST API

rs-es Introduction An ElasticSearch client for Rust via the REST API. Targetting ElasticSearch 2.0 and higher. Other clients For later versions of Ela

Ben Ashford 218 Dec 27, 2022
An Elasticsearch REST API client for Rust

elastic elastic is an efficient, modular API client for Elasticsearch written in Rust. The API is targeting the Elastic Stack 7.x. elastic provides st

null 249 Oct 18, 2022
An etcd client library for Rust.

etcd An etcd client library for Rust. etcd on crates.io Documentation for the latest crates.io release Running the tests Install Docker and Docker Com

Jimmy Cuadra 138 Dec 27, 2022