I'm trying sqlx for the first time these days, sorry if this is a dumb question.

I'm writing a function that I want to take both PgPool and Transaction<Postgres>.

I'm using the below (SIMPLIFIED) code:

#[derive(Debug, Default, sqlx::FromRow)]
pub struct PgPlayer {
    pub id: String,
    pub created_at: time::OffsetDateTime,
    pub updated_at: Option<time::OffsetDateTime>,
    pub name: String,
    pub team: Option<String>,

async fn player_delete(&self, id: &str) -> Result<()> {
  let mut tx = self.pool.begin().await?;

  let player_in_db = query_by_id(&mut tx, id).await?;

  // Do something with player_in_db here...

  delete(&mut tx, id).await?;



pub fn query_by_id<'a>(
  db: impl sqlx::PgExecutor<'a> + 'a,
  id: &'a str,
) -> Pin<Box<dyn Future<Output = Result<PgPlayer>> + Send + 'a>> {
  Box::pin(async move {
      let player = sqlx::query_as::<_, PgPlayer>(
          r#"SELECT * FROM players WHERE id = $1"#,


pub async fn delete<'a>(
  db: impl sqlx::PgExecutor<'a>,
  id: &str,
) -> Result<()> {
  sqlx::query(r#"DELETE FROM players WHERE id = $1"#)


Is this good enough or is there a better way to write it (maybe avoiding the lifetimes in impl sqlx::PgExecutor<'a>)?

  • \$\begingroup\$ I see neither PgPool nor Transaction<Postgres> being used anywhere in your code. \$\endgroup\$ Jan 2 at 11:25
  • \$\begingroup\$ As for the lifetimes: No, not really. sqlx::PgExecutor needs a specified lifetime, which would be the lifetime of the user. You could set it to 'static, but this would be an unnecessary widening of the required lifetime. \$\endgroup\$ Jan 2 at 11:30


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Browse other questions tagged or ask your own question.