Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Save vector of custom type error into String type in clickhouse #72

Open
dylankyc opened this issue Jun 25, 2023 · 1 comment
Open

Save vector of custom type error into String type in clickhouse #72

dylankyc opened this issue Jun 25, 2023 · 1 comment

Comments

@dylankyc
Copy link

Hi, I want to save vector of Filters into monitor table:

#[derive(Debug, Serialize, Deserialize, Row)]
pub struct Filter {
    pub name: String,
    pub operator: String,
}
#[derive(Debug, Serialize, Deserialize, Row)]
pub struct Monitor {
    #[serde(with = "clickhouse::serde::uuid")]
    pub uuid: Uuid,
    pub name: String,
    // Use the custom `filter_serde` for the `filters` field
    // #[serde(with = "filter_serde")]
    pub filters: Vec<Filter>,
}

pub async fn create_table(client: &Client) -> Result<(), Box<dyn std::error::Error>> {
    client
        .query(
            "
            CREATE TABLE IF NOT EXISTS monitor(
                uuid UUID,
                name LowCardinality(String),
                filters Nullable(String)
            )
            ENGINE = MergeTree
            ORDER BY name
        ",
        )
        .execute()
        .await
        .map_err(|err: Error| err.into())
}


pub async fn insert_monitor(
    client: &Client,
    monitor: &Monitor,
) -> Result<(), Box<dyn std::error::Error>> {
    let mut insert = client.insert(table_name)?;
    insert.write(monitor).await?;
    insert.end().await?;
    Ok(())
}

let now = OffsetDateTime::now_utc();

let filter = Filter {
    name: "123".to_string(),
    operator: "=".to_string(),
};
let filters = vec![filter];

let monitor = Monitor{
    uuid: Uuid::new_v4(),
    name: "test".to_string(),
    filters: filters
}

let _ = insert_monitor(&client, &monitor).await?;

However, there's an error during the insertion.

Error: BadResponse("Code: 33. DB::Exception: Cannot read all data. Bytes read: 9. Bytes expected: 97.: (at row 2)\n: While executing BinaryRowInputFormat. (CANNOT_READ_ALL_DATA) (version 22.7.2.1)")

How to write a vector of custom type(Vec<Filter>) and insert into the table?

Do I need to write serialize and deserialize functions and specify with #[serde(with = "filter_serde")] in filters field?

Thanks.

@loyd
Copy link
Collaborator

loyd commented Jul 4, 2023

Hello,
I do not totally understand the problem. You're trying to insert Vec<String> into String. The schema should contain Array(String) or you can use serde(with) to somehow transform Vec<String> into String on your own.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants