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
Joining UPSERTs with query_one and owned parameters #927
Comments
You can use an let future1 = async {
let params = vec![...];
client.query_one(query_string, ¶ms).await
}; |
I'm generating the futures from an iterator:
This still causes issues:
|
You shouldn't need the vec: async {
client.query_one(
&statement,
&[
&channel_id,
&Side::Spender,
// ...
]
).await
} |
It's still causing problems and it suggests to use PS: I forced the client to be a I still don't think this is very pretty but it does work. pub async fn spend_amount(
pool: DbPool,
channel_id: ChannelId,
delta_balances: Balances<CheckedState>,
) -> Result<(Vec<Accounting>, Vec<Accounting>), PoolError> {
let client = &pool.get().await?;
let statement = client.prepare_cached(UPDATE_ACCOUNTING_STATEMENT).await?;
// Earners
let earners_futures = delta_balances.earners.into_iter().map(|(earner, amount)| {
let statement = statement.clone();
async move {
client
.query_one(&statement, &[&channel_id, &Side::Earner, &earner, &amount])
.await
.map(|row| Accounting::from(&row))
}
});
// Spenders
let spenders_futures = delta_balances
.spenders
.into_iter()
.map(|(spender, amount)| {
let statement = statement.clone();
async move {
client
.query_one(
&statement,
&[&channel_id, &Side::Spender, &spender, &amount],
)
.await
.map(|row| Accounting::from(&row))
}
});
let earners = join_all(earners_futures);
let spenders = join_all(spenders_futures);
// collect all the Accounting updates into Vectors
let (earners, spenders) = join(earners, spenders).await;
// Return an error if any of the Accounting updates failed
Ok((
earners.into_iter().collect::<Result<_, _>>()?,
spenders.into_iter().collect::<Result<_, _>>()?,
))
} |
Ah yeah you sometimes need to use |
Ok, thanks for the help, as always 😋 |
Hello,
I'm doing multiple UPSERT queries with RETURNING statement that I want to join in single future. This can be achieve only with
query_raw
sincequery_one
takes a&[...]
and the parameters don't live long enough, while we can use:vec![Box::new(param1) as Box<dyn ToSql + Sync + Send>,]
withquery_raw
.However, this has some drawbacks, mainly I have to manually:
RowStream
the same wayquery_one
doesError::RowCount
error and wrap thetokio_postgres::Error
A solution to fix this would need to either:
IntoIterator
parameters ofquery_one
andquery_opt
While it's good that it takes reference to the parameters, this has caused me multiple problems in the past too.
It would be very beneficial, in my opinion, to have such an improvement for owned types as I still think it's a rough edge that needs some polishing.
What do you think about that?
The text was updated successfully, but these errors were encountered: