Hi folks,
This has been covered a good bit in StackOverflow questions & in other places, but I have yet to find a solution that I'm happy with... I want to create an UPDATE
statement with a variable number of columns. Something like
coffees.filter(_.id === id)
.map(t => change.cols(t)) // cols(t) returns Seq[Rep[_]]
.update(change.values) // values returns a Seq[_]
I feel like there could be a way to do this with a custom Shape
(like TupleShape
but for Seq
), but I was hoping for some more experienced folks to tell me if this is a futile endeavor or if it's a viable approach.
There's also this gist but I'd rather not have to create a custom driver or rely on regexes to manipulate the query.
Seq
, as I'd imagine a lot of type information (for each column) will get lost away to Any
. I'd be tempted to use something like slick.collection.heterogeneous.HList
, and there would be some fun/challenging type-level methods to get the types to exactly line up for cols and values.
change
on.
Thanks, Richard. In this case, I'm okay with missing out on some type safety. For the moment, I've ended up with something along these lines:
SQLActionBuilder(
Seq(s"UPDATE $tableName SET ",
cols.map(_.getDumpInfo.mainInfo + " = ?").mkString(", "),
" WHERE ID = ?",
" LIMIT 1",
),
(_: Unit, pp: PositionedParameters) => {
(values :+ id).foreach {
case v: Boolean => pp.setBoolean(v)
case v: Byte => pp.setByte(v)
case v: Date => pp.setDate(v)
case v: Double => pp.setDouble(v)
case v: Float => pp.setFloat(v)
case v: Int => pp.setInt(v)
case v: Long => pp.setLong(v)
case v: Short => pp.setShort(v)
case v: String => pp.setString(v)
case v: Time => pp.setTime(v)
case v: Timestamp => pp.setTimestamp(v)
case v => throw new SQLException("update doesn't know how to handle parameter (" + v + ")")
}
}).asUpdate
It's not quite complete because it doesn't handle NULLs, but it works for my current needs.
Given the following for PostgreSQL
CREATE TABLE IF NOT EXISTS X(id INT PRIMARY KEY, name VARCHAR not null);
select *from X x where (x.id, x.name) in ( (1,'foo'), (2,'bar'))
;
how do I do this with Slick 3.3.3? The compiler never seems to agree with me
inSet
doesn't seem to support tuples. We might be able to teach Slick how to do that, but the workaround would be to transform into a (id ===1 && name == "foo") or (id === 2 && name === "bar")
. Sounds horrible, but the code isn't too much. Old example: https://github.com/d6y/list-of-tuples/blob/eaa2903332d7797ac38d8807fa598fd2a5aad344/src/main/scala/or-example.scala#L52-L55
SELECT * FROM (VALUES
(CAST('316df2ac-14d0-468e-8e2e-0e5a54a8abca' as uuid)),
(CAST('47700d3b-b1fc-402f-80e5-a113ae792aca' as uuid)),
(CAST('965c0657-0bdd-4842-a127-9547b9c58ca3' as uuid))
) AS q (col1)
left join table on col1 = employee_id;
ids
would need to be a Query[Rep[X]], X, Seq]
where X
is whatever the type is for the uuid. I
Long
s I think ids
could be: val ids: Query[Rep[Long], Long, Seq] = Query(1L) ++ Query(3L) ++ Query(5L)
Query.apply
directly like that for a real application)
I am trying to run this query:
sql"""select distinct r_.server_request_id, r_.raw_request from #$tableName r_ where r_.server_request_id in ( #$sids ) and r_.created < #$downTime and r_.created > #$tillTime""".as[(String, String)]
when I look at raw sql
s""" select distinct r_.server_request_id, r_.raw_request from #$tableName r_ where r_.server_request_id in (#$sids) and r_.created < #$downTime and r_.created > #$tillTime""".stripMargin
And paste it to run on postgres with values it prints - I get correct result, however with above sql""" syntax I get empty result -- any suggestions for me would be great
I tried writing non sql way too:
table.map(server_request_id, raw_request, created_date).filter(dates).filter(_.server_request_id inSet serverRequestIdList).map(server_request_id, created_date).result
but seems to give me same empty vector as result...
Hey guys, I've opened a Pull Request to an issue, but AppVeyor is broking and I don't have idea why.
Can anyone help me? :pray:
cleanUp
perhaps. https://books.underscore.io/essential-slick/essential-slick-3.html#andfinally-and-cleanup
private class DbWeatherCalculations(tag: Tag)
extends Table[WeatherCalculationRepresentation](tag, Some("bill_management_v2"), "weather_calculations") {
def id = column[Long]("id", O.PrimaryKey, O.AutoInc)
def createdAt = column[Timestamp]("created_at", O.AutoInc)
def billItemId = column[Long]("bill_item_id")
def name = column[String]("name")
def value = column[Double]("value")
def units = column[String]("units")
def billRecordId = column[Long]("bill_record_id")
def * = (id.?, createdAt.?, billItemId, name, value, units, billRecordId)
.<>( (WeatherCalculationRepresentation.apply _).tupled, WeatherCalculationRepresentation.unapply)
}
Hi,
I have this problem where 'units' has it's own data type in postgresql which is kind of enumeration. When I try to make an insertion I get this error:
ERROR: column \"units\" is of type public.units but expression is of type character varying\n Hint: You will need to rewrite or cast the expression.\n
Any suggestion about how I can cast the column 'units' to the one from db? Thanks