Search code examples
postgresqlscalaslick

Combining a non-*-projection and "returning" in Slick


I have two working statements to insert a row into a table named document with Slick.

The first one inserts all columns, taken from the row object and returns the ID generated by Postgres:

(Tables.Document returning Tables.Document.map(_.id)) +=
    DocumentRow(id=-1, name="Name", fulltext="The text")

The second one ignores the column named fulltext and only inserts the name but does not return the generated ID:

Tables.Document.map(r => (r.name)) += ("Name")

How can I combine both (limiting the insert to a subset of columns and returning the generated ID at the same time)?

Background:

The reason why I want to exclude the fulltext column from the insert is the fact that it is of Postgres type tsvector, but the generated Slick code treats it as a String. At insert time the value (even if null or None) is converted into some text type which is incompatible with tsvector and raises an exception. I found no solution to insert a tsvector without an additional library. Please comment if you think there is and I should be rather following this path.


Solution

  • Although I believe the right way is to fix tsvector issue, I don't have enough experience with Postres to help you with it. As for your workaround, you can do it and the code should look something like this:

    (Tables.Document.map(r => (r.name)) returning Tables.Document.map(_.id)) += ("Name")
    

    If you split it into parts you can see that first you create a Query as in your second example but then rather than apply += to it immediately you first chain it with returning and only then call +=.

    P.S. What is the issue with using some additional Postres-aware library?