Skip to content

Commit

Permalink
docs: new JSON examples with ClickHouse 24.10 (#171)
Browse files Browse the repository at this point in the history
  • Loading branch information
slvrtrn authored Nov 1, 2024
1 parent 1fc1f39 commit 0290fba
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 2 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -438,8 +438,8 @@ How to choose between all these features? Here are some considerations:
}
```
</details>
* `JSON`, `Variant`, `Dynamic` types are not supported for now.
* [New `JSON` data type](https://clickhouse.com/docs/en/sql-reference/data-types/newjson) is currently supported as a string when using ClickHouse 24.10+. See [this example](examples/data_types_new_json.rs) for more details.
* `Variant`, `Dynamic` types are not supported for now.
See also the additional examples:
Expand Down
1 change: 1 addition & 0 deletions examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ If something is missing, or you found a mistake in one of these examples, please

- [data_types_derive_simple.rs](data_types_derive_simple.rs) - deriving simpler ClickHouse data types in a struct. Required cargo features: `time`, `uuid`.
- [data_types_derive_containers.rs](data_types_derive_containers.rs) - deriving container-like (Array, Tuple, Map, Nested, Geo) ClickHouse data types in a struct.
- [data_types_new_json.rs](data_types_new_json.rs) - working with the [new JSON data type](https://clickhouse.com/docs/en/sql-reference/data-types/newjson) as a String.

### Special cases

Expand Down
75 changes: 75 additions & 0 deletions examples/data_types_new_json.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
use clickhouse_derive::Row;
use serde::{Deserialize, Serialize};

use clickhouse::sql::Identifier;
use clickhouse::{error::Result, Client};

// Requires ClickHouse 24.10+, as the `input_format_binary_read_json_as_string` and `output_format_binary_write_json_as_string` settings were added in that version.
// Inserting and selecting a row with a JSON column as a string.
// See also: https://clickhouse.com/docs/en/sql-reference/data-types/newjson

#[tokio::main]
async fn main() -> Result<()> {
let table_name = "chrs_data_types_new_json";
let client = Client::default()
.with_url("http://localhost:8123")
// All these settings can instead be applied on the query or insert level with the same `with_option` method.
// Enable new JSON type usage
.with_option("allow_experimental_json_type", "1")
// Enable inserting JSON columns as a string
.with_option("input_format_binary_read_json_as_string", "1")
// Enable selecting JSON columns as a string
.with_option("output_format_binary_write_json_as_string", "1");

client
.query(
"
CREATE OR REPLACE TABLE ?
(
id UInt64,
data JSON
) ENGINE MergeTree ORDER BY id;
",
)
.bind(Identifier(table_name))
.execute()
.await?;

let row = Row {
id: 1,
data: r#"
{
"name": "John Doe",
"age": 42,
"phones": [
"+123 456 789",
"+987 654 321"
]
}"#
.to_string(),
};

let mut insert = client.insert(table_name)?;
insert.write(&row).await?;
insert.end().await?;

let db_row = client
.query("SELECT ?fields FROM ? LIMIT 1")
.bind(Identifier(table_name))
.fetch_one::<Row>()
.await?;

println!("{db_row:#?}");

// You can then use any JSON library to parse the JSON string, e.g., serde_json.
let json_value: serde_json::Value = serde_json::from_str(&db_row.data).expect("Invalid JSON");
println!("Extracted name from JSON: {}", json_value["name"]);

Ok(())
}

#[derive(Debug, Row, Serialize, Deserialize)]
pub struct Row {
id: u64,
data: String,
}

0 comments on commit 0290fba

Please sign in to comment.