gpt4 book ai didi

scala - Slick 3.0.0 中如果不存在则插入

转载 作者:行者123 更新时间:2023-12-03 01:23:10 26 4
gpt4 key购买 nike

我正在尝试插入如果不存在,我发现 this post适用于 1.0.1、2.0。

我在 the docs of 3.0.0 中发现使用事务性的代码片段

val a = (for {
ns <- coffees.filter(_.name.startsWith("ESPRESSO")).map(_.name).result
_ <- DBIO.seq(ns.map(n => coffees.filter(_.name === n).delete): _*)
} yield ()).transactionally

val f: Future[Unit] = db.run(a)

我正在努力编写插入逻辑(如果该结构不存在)。我是 Slick 的新手,对 Scala 的经验很少。这是我尝试在事务外部不存在时进行插入...

val result: Future[Boolean] = db.run(products.filter(_.name==="foo").exists.result)
result.map { exists =>
if (!exists) {
products += Product(
None,
productName,
productPrice
)
}
}

但是我如何将其放入事务 block 中?这是我能走的最远的距离:

val a = (for {
exists <- products.filter(_.name==="foo").exists.result
//???
// _ <- DBIO.seq(ns.map(n => coffees.filter(_.name === n).delete): _*)
} yield ()).transactionally

提前致谢

最佳答案

可以使用单个insert ... if not contains 查询。这可以避免多次数据库往返和竞争条件(根据隔离级别,事务可能不够)。

def insertIfNotExists(name: String) = users.forceInsertQuery {
val exists = (for (u <- users if u.name === name.bind) yield u).exists
val insert = (name.bind, None) <> (User.apply _ tupled, User.unapply)
for (u <- Query(insert) if !exists) yield u
}

Await.result(db.run(DBIO.seq(
// create the schema
users.schema.create,

users += User("Bob"),
users += User("Bob"),
insertIfNotExists("Bob"),
insertIfNotExists("Fred"),
insertIfNotExists("Fred"),

// print the users (select * from USERS)
users.result.map(println)
)), Duration.Inf)

输出:

Vector(User(Bob,Some(1)), User(Bob,Some(2)), User(Fred,Some(3)))

生成的 SQL:

insert into "USERS" ("NAME","ID") select ?, null where not exists(select x2."NAME", x2."ID" from "USERS" x2 where x2."NAME" = ?)

Here's the full example on github

关于scala - Slick 3.0.0 中如果不存在则插入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30706193/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com