-
Notifications
You must be signed in to change notification settings - Fork 94
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
How to get batch LWT statement result? #998
Comments
You can know it based on Result obtained from
|
Thank you for such quick response, but it is not 100% clear to me. When I'm experimenting in db console, such batch returns "ok":
And the first column in that returned row contains status "applied: false", so it looks like result with the rows, not the error. |
@Lorak-mmk any ideas? |
Well, I wrote minimal repro of my case, and yes - on a batch query there is a QueryResult that looks like:
And got every statement status in a batch like this: let (value_idx, _) = query_result.get_column_spec("[applied]").expect("No value column found");
let mut row_index = 1;
for row in query_result.rows.expect("no rows found") {
println!("row #{}: applied = {:?}", row_index, row.columns[value_idx]);
row_index += 1;
} output:
I can't say this is very convenient, and hardcoded "[applied]" column name seems not elegant, but it is working. May be you can add one more example about how to work with batches? use scylla::{Session, SessionBuilder};
use scylla::batch::Batch;
use scylla::transport::errors::QueryError;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Create connection
let uri = "127.0.0.1:9042".to_string();
println!("Connecting to {} ...", uri);
let session: Session = SessionBuilder::new()
.known_node(uri)
.user("cassandra", "cassandra")
.schema_agreement_interval(std::time::Duration::from_secs(1)) // check every second for schema agreement if not agreed first check
.build()
.await?;
let schema_version = session.await_schema_agreement().await?;
println!("Schema version: {}", schema_version);
session.query("CREATE KEYSPACE IF NOT EXISTS examples_ks WITH REPLICATION = {'class' : 'NetworkTopologyStrategy', 'replication_factor' : 1}", &[]).await?;
match session.await_schema_agreement().await {
Ok(_schema_version) => println!("Schema is in agreement in time"),
Err(QueryError::RequestTimeout(_)) => println!("Schema is NOT in agreement in time"),
Err(err) => panic!("Query error {}", err),
};
session
.query("DROP TABLE IF EXISTS examples_ks.cf", &[])
.await?;
session
.query("CREATE TABLE IF NOT EXISTS examples_ks.cf (account_d INT, updated_at TIMESTAMP, value BIGINT, PRIMARY KEY ( (account_d) ))", &[])
.await?;
session.await_schema_agreement().await?;
println!("OK1");
// add row
let mut batch: Batch = Default::default();
batch.append_statement("UPDATE examples_ks.cf SET value = 1, updated_at = currentTimestamp() WHERE account_d = 20 IF updated_at = null AND value = null;");
let prepared: Batch = session.prepare_batch(&batch).await?;
let res = session.batch(&prepared, ((), (), )).await?;
println!("OK2 {:?}", res);
let (value_idx, _) = res.get_column_spec("[applied]").expect("No value column found");
let mut row_index = 1;
for row in res.rows.expect("no rows found") {
println!("row #{}: applied = {:?}", row_index, row.columns[value_idx]);
row_index += 1;
}
println!("OK3");
Ok(())
} |
Did you try with more than one statement in batch? If memory serves me right there will always be one row in response, which indicates if the batch was applied or not. Your code looks like you assume there will be a row per a statement in batch. |
Quick test with two statements in a batch: let mut batch: Batch = Default::default();
batch.append_statement("UPDATE examples_ks.cf SET value = 1, updated_at = '2024-05-13 15:08:59.152' WHERE account_d = 20 IF updated_at = null AND value = null;");
batch.append_statement("UPDATE examples_ks.cf SET value = 2, updated_at = '2024-05-13 16:08:59.152' WHERE account_d = 20 IF updated_at = '2024-05-13 15:08:59.152' AND value = 1;");
let prepared: Batch = session.prepare_batch(&batch).await?;
let res = session.batch(&prepared, ((), (), )).await?;
println!("OK2 {:?}", res);
let (value_idx, _) = res.get_column_spec("[applied]").expect("No value column found");
let mut row_index = 1;
for row in res.rows.expect("no rows found") {
println!("row #{}: applied = {:?}", row_index, row.columns[value_idx]);
row_index += 1;
} Output:
So, we have row per statement, but actually I expected only one row in query result because first statement has not been applied, and batch should be stopped because of all or nothing rule. EDIT: or may be I'm wrong and second statement even didn't run because of first statement failure.. And for the whole batch status it is enough to check only first row applied state.. |
@fortunado - I encourage you to ask questions over https://forum.scylladb.com/ (if you feel there's a bug in the driver, that is the right place though to discuss it) |
Hi!
I'm running 3 statements in a batch and I'd like to get to know if batch was applied or not.
Please, advise.
Thanks.
The text was updated successfully, but these errors were encountered: