Skip to main content

rust_data_processing/ingestion/
snowflake.rs

1//! Snowflake load: write Parquet to a stage URI (S3 / GCS / ABFS / `file://`), then optional `COPY INTO`.
2//!
3//! Automatic `COPY INTO` requires `SNOWFLAKE_USER` / `SNOWFLAKE_PASSWORD` and a future native driver;
4//! today Rust always lands data on the stage via [`export_dataset_to_object_store_uri`].
5
6use crate::error::{IngestionError, IngestionResult};
7use crate::types::DataSet;
8
9use super::object_store::export_dataset_to_object_store_uri;
10
11/// Write `ds` as Parquet to `stage_uri` (object-store URI Rust can write).
12pub fn write_dataset_to_snowflake_stage(stage_uri: &str, ds: &DataSet) -> IngestionResult<usize> {
13    let rows = ds.row_count();
14    export_dataset_to_object_store_uri(stage_uri, ds)?;
15    Ok(rows)
16}
17
18/// Optional `COPY INTO` — not linked in-tree; stage write is the supported path.
19pub fn copy_into_table_from_stage(
20    account_url: &str,
21    warehouse: Option<&str>,
22    database: Option<&str>,
23    schema: Option<&str>,
24    table: &str,
25    stage_uri: &str,
26    role: Option<&str>,
27) -> IngestionResult<()> {
28    let _ = (
29        account_url,
30        warehouse,
31        database,
32        schema,
33        table,
34        stage_uri,
35        role,
36    );
37    if std::env::var("SNOWFLAKE_USER").is_ok() && std::env::var("SNOWFLAKE_PASSWORD").is_ok() {
38        return Err(IngestionError::SchemaMismatch {
39            message: "SNOWFLAKE_USER/PASSWORD are set but in-tree COPY INTO is not linked yet; run COPY FROM the staged Parquet in Snowflake SQL or add snowflake driver in a future release".to_string(),
40        });
41    }
42    Err(IngestionError::SchemaMismatch {
43        message: "COPY INTO skipped: set SNOWFLAKE_USER and SNOWFLAKE_PASSWORD to enable (driver not linked in this build)".to_string(),
44    })
45}