GCP BigQuery Client (Rust)

github crates.io docs.rs build status

An ergonomic async client library for GCP BigQuery. * Support all BigQuery API endpoints (not all covered by unit tests yet) * Support Service Account Key authentication and other yup-oauth2 mechanisms * Create tables and rows via builder patterns * Persist complex Rust structs in structured BigQuery tables * Async API


Contributions are welcome.
Please post your suggestions and ideas on this GitHub discussion section.


Example

This example performs the following operations: * Load a set of environment variables to set $PROJECT_ID, $DATASET_ID, $TABLE_ID and $GOOGLE_APPLICATION_CREDENTIALS * Init the BigQuery client * Create a dataset in the GCP project $PROJECT_ID * Create a table in the previously created dataset (table schema) * Insert a set of rows in the previously created table via the BigQuery Streaming API. The inserted rows are based on a regular Rust struct implementing the trait Serialize. * Perform a select query on the previously created table * Drop the table previously created * Drop the dataset previously created

```rust // Read configuration parameters from environment variables let (ref projectid, ref datasetid, ref tableid, ref gcpsakey) = envvars();

// Init BigQuery client let client = gcpbigqueryclient::Client::fromserviceaccountkeyfile(gcpsakey).await;

// Create dataset let createddataset = client.dataset().create(projectid, Dataset::new(datasetid)).await?; println!( "Dataset '{}.{}' created", createddataset.projectid(), createddataset.dataset_id() );

// Create table schema let table = Table::new( projectid, datasetid, tableid, TableSchema::new(vec![ TableFieldSchema::integer("intvalue"), TableFieldSchema::float("floatvalue"), TableFieldSchema::bool("boolvalue"), TableFieldSchema::string("stringvalue"), TableFieldSchema::record( "recordvalue", vec![ TableFieldSchema::integer("intvalue"), TableFieldSchema::string("stringvalue"), TableFieldSchema::record( "recordvalue", vec![ TableFieldSchema::integer("intvalue"), TableFieldSchema::string("string_value"), ], ), ], ), ]), );

let createdtable = client.table().create(projectid, datasetid, table).await?; println!( "Table '{}.{}.{}' created", createdtable.projectid(), createdtable.datasetid(), createdtable.table_id() );

// Insert data via BigQuery Streaming API let mut insertrequest = TableDataInsertAllRequest::new(); insertrequest.addrow( None, MyRow { intvalue: 1, floatvalue: 1.0, boolvalue: false, stringvalue: "first".into(), recordvalue: FirstRecordLevel { intvalue: 10, stringvalue: "sublevel1.1".into(), recordvalue: SecondRecordLevel { intvalue: 20, stringvalue: "leaf".tostring(), }, }, }, )?; insertrequest.addrow( None, MyRow { intvalue: 2, floatvalue: 2.0, boolvalue: true, stringvalue: "second".into(), recordvalue: FirstRecordLevel { intvalue: 11, stringvalue: "sublevel1.2".into(), recordvalue: SecondRecordLevel { intvalue: 21, stringvalue: "leaf".to_string(), }, }, }, )?;

client .tabledata() .insertall(projectid, datasetid, tableid, insert_request) .await?;

// Query let mut rs = client .job() .query( projectid, QueryRequest::new(format!( "SELECT COUNT(*) AS c FROM {}.{}.{}", projectid, datasetid, tableid )), ) .await?; while rs.nextrow() { println!("Number of rows inserted: {}", rs.geti64byname("c")?.unwrap()); }

// Delete the table previously created client.table().delete(projectid, datasetid, table_id).await?;

// Delete the dataset previously created client.dataset().delete(projectid, datasetid, true).await?; ```

Status

The API of this crate is still subject to change up to version 1.0.

List of endpoints implemented: - [X] Dataset - All methods - [X] Table - All methods - [X] Tabledata - All methods - [X] Job - All methods - [X] Model - All methods (not tested) - [X] Project (not tested) - [X] GetServiceAccount - [] List - [X] Routine - All methods (not tested)

License

Licensed under either of Apache License, Version 2.0 or MIT license at your option.


Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in this crate by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.