rustrust-polarsrust-sqlx

How to get a column as Option<String> out of a polars DataFrame?


I am trying to get a Vec<Option<String>> so I can pass it to sqlx with null values intact. Based on this SO question, I've tried:

let names: Vec<Option<String>> = merged_df
    .column("description")?
    .str()?
    .into_iter()
    .map(|s| s.to_string())
    .collect();

But this is failing with:

 1  error[E0599]: the method `to_string` exists for enum `Option<&str>`, but its trait bounds were not satisfied
     --> rust/load_all.rs:569:20
      |
 569  |         .map(|s| s.to_string())
      |                    ^^^^^^^^^ method cannot be called on `Option<&str>` due to unsatisfied trait bounds
      |
     ::: /Users/nick/.rustup/toolchains/stable-aarch64-apple-darwin/lib/rustlib/src/rust/library/core/src/option.rs:570:1
      |
 570  | pub enum Option<T> {
      | ------------------ doesn't satisfy `_: TemporalMethods`, `std::option::Option<&str>: AsSeries`, `std::option::Option<&str>: ToString
 ` or `std::option::Option<&str>: std::fmt::Display`
      |
      = note: the following trait bounds were not satisfied:
              `std::option::Option<&str>: AsSeries`
              which is required by `std::option::Option<&str>: polars::prelude::TemporalMethods`
              `std::option::Option<&str>: std::fmt::Display`
              which is required by `std::option::Option<&str>: ToString`

How can I get this to work?


Solution

  • You're missing one map(). You need two: one for the iterator, the other for the Option:

    let names: Vec<Option<String>> = merged_df
        .column("description")?
        .str()?
        .into_iter()
        .map(|s| s.map(|s| s.to_string()))
        .collect();
    

    Side note, you should prefer working with native Polars operations than converting like that. It'll be more efficient.