# Get or create does not compile

**URL:** <https://discourse.diesel.rs/t/get-or-create-does-not-compile/76>\
**Category:** Uncategorized\
**Created:** [March 15, 2019, 12:17pm UTC](https://discourse.diesel.rs/t/get-or-create-does-not-compile/76 "2019-03-15T12:17:41Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![dns2utf8](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.diesel.rs/dns2utf8/32/44_2.png) [@dns2utf8](https://discourse.diesel.rs/u/dns2utf8)\
**Post date:** [March 15, 2019, 12:17pm UTC](https://discourse.diesel.rs/t/get-or-create-does-not-compile/76/1 "2019-03-15T12:17:41Z")

</div>

Hi everybody

I am currently processing a lot of files. So I want to store the progress in PostgreSQL.  
It works so far except one thing:

```auto
fn get_file_or_create(connection: &PgConnection, path: &String) -> models::File {
    use schema::files::dsl::*;

    let candidates = files
        .filter(path.eq(path))
        .load::<models::File>(connection)
        .expect("unable to load files");
    for file in candidates {
        return file;
    }

    // create
    diesel::insert_into(files)
        .values((path.eq(path), status.eq(models::SOURCE_STATUS_PROCESSING)))
        .get_result(connection)
        .expect("unable to create new file")
}

```

This gives me this error:

```auto
error[E0271]: type mismatch resolving `<() as diesel::query_source::AppearsInFromClause<schema::files::table>>::Count == diesel::query_source::Once`
  --> src/main.rs:95:10
   |
95 | .get_result(connection)
   | ^^^^^^^^^^ expected struct `diesel::query_source::Never`, found struct `diesel::query_source::Once`
   |
   = note: expected type `diesel::query_source::Never`
              found type `diesel::query_source::Once`

```

Did I miss something? Or is there a function that already provides that?  
I am using rust 1.33.0 with edition 2018 on Arch Linux.  
In other parts of the code I can insert and select other data.

Some more relevant source code:

```auto
/// models.rs
#[derive(Queryable, Identifiable, PartialEq)]
pub struct File {
    pub id: i32,
    pub path: String,
    pub status: String,
}

pub const SOURCE_STATUS_PROCESSING: &'static str = "Processing";
pub const SOURCE_STATUS_Complete: &'static str = "Complete";

```

```auto
/// schema.rs
table! {
    files (id) {
        id -> Int4,
        path -> Text,
        status -> Text,
    }
}

```

Cheers,  
Stefan

---

<div class="post-metadata">

**Author:** ![dns2utf8](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.diesel.rs/dns2utf8/32/44_2.png) [@dns2utf8](https://discourse.diesel.rs/u/dns2utf8)\
**Post date:** [March 15, 2019, 12:39pm UTC](https://discourse.diesel.rs/t/get-or-create-does-not-compile/76/2 "2019-03-15T12:39:40Z")

</div>

Nevermind, I found the error. It was overlaying symbols.  
Here is the working code:

```auto
fn get_file_or_create(connection: &PgConnection, new_path: &String) -> models::File {
    use schema::files::dsl::*;

    let candidates = files
        .filter(path.eq(new_path))
        .load::<models::File>(connection)
        .expect("unable to load files");
    for file in candidates {
        return file;
    }
    // create
    /*let new_file = models::NewFile {
        path: new_path,
        status: models::SOURCE_STATUS_PROCESSING,
    };*/
    diesel::insert_into(files)
        //.values(&new_file)
        .values((path.eq(new_path), status.eq(models::SOURCE_STATUS_PROCESSING)))
        .get_result(connection)
        .expect("unable to create new file")
}

```

Nevertheless, would you consider adding a get\_or\_create function?

Cheers,  
Stefan

---

<div class="post-metadata">

**Author:** ![sean](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.diesel.rs/sean/32/2_2.png) [@sean](https://discourse.diesel.rs/u/sean)\
**Post date:** [March 16, 2019, 2:01pm UTC](https://discourse.diesel.rs/t/get-or-create-does-not-compile/76/3 "2019-03-16T14:01:42Z")

</div>

See [http://docs.diesel.rs/diesel/pg/upsert/index.html](http://docs.diesel.rs/diesel/pg/upsert/index.html) and [https://www.postgresql.org/docs/current/sql-insert.html#SQL-ON-CONFLICT](https://www.postgresql.org/docs/current/sql-insert.html#SQL-ON-CONFLICT)

---

<div class="post-metadata">

**Author:** ![dns2utf8](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.diesel.rs/dns2utf8/32/44_2.png) [@dns2utf8](https://discourse.diesel.rs/u/dns2utf8)\
**Post date:** [March 17, 2019, 9:28pm UTC](https://discourse.diesel.rs/t/get-or-create-does-not-compile/76/4 "2019-03-17T21:28:42Z")

</div>

Hi sean

Thanks for the response. I tried to get it working with code and SQL, but I can only get a syntax or type error:

```sql
WITH ins AS (
    INSERT INTO files (path, status) VALUES ('abc', 'bbb') 
    ON CONFLICT (SELECT path FROM files WHERE path = 'abc')
    DO UPDATE SET path = NULL 
    WHERE FALSE RETURNING id
) SELECT id from ins UNION ALL SELECT id from files WHERE path = 'abc';

```

Did you mean something like that?

Best,  
Stefan
