Slick 3.1.1 在没有 AutoInc 的情况下将元素插入数据库
Slick 3.1.1 insert element into database without AutoInc
我正在尝试将一个元素简单地插入到数据库中,而 table 上没有 autoinc 标志。
这是 table 定义,我定义了所有合适的映射器:
class BlockHeaderTable(tag: Tag) extends Table[BlockHeader](tag,"block_headers") {
def hash = column[DoubleSha256Digest]("hash", O.PrimaryKey)
def version = column[UInt32]("version")
def previousBlockHash = column[DoubleSha256Digest]("previous_block_hash")
def merkleRootHash = column[DoubleSha256Digest]("merkle_root_hash")
def time = column[UInt32]("time")
def nBits = column[UInt32]("n_bits")
def nonce = column[UInt32]("nonce")
def * = (hash, version, previousBlockHash, merkleRootHash, time, nBits, nonce).<>[BlockHeader,
(DoubleSha256Digest, UInt32, DoubleSha256Digest, DoubleSha256Digest, UInt32, UInt32, UInt32)](blockHeaderApply,blockHeaderUnapply)
}
我正在尝试为此 table 创建一个简单的插入函数。这是我的尝试:
override val table = TableQuery[BlockHeaderTable]
def create(blockHeader: BlockHeader): Future[BlockHeader] = {
val insertAction = table += blockHeader
database.run(insertAction)
}
我收到以下类型的错误:
chris@chris-870Z5E-880Z5E-680Z5E:~/dev/bitcoins-spv-node$ sbt compile
[info] Loading project definition from /home/chris/dev/bitcoins-spv-node/project
[info] Set current project to bitcoins-spv-node (in build file:/home/chris/dev/bitcoins-spv-node/)
[info] Compiling 1 Scala source to /home/chris/dev/bitcoins-spv-node/target/scala-2.11/classes...
[error] /home/chris/dev/bitcoins-spv-node/src/main/scala/org/bitcoins/spvnode/models/BlockHeaderDAO.scala:30: type mismatch;
[error] found : slick.profile.FixedSqlAction[Boolean,slick.dbio.NoStream,slick.dbio.Effect.Write]
[error] required: slick.dbio.DBIOAction[org.bitcoins.core.protocol.blockchain.BlockHeader,slick.dbio.NoStream,Nothing]
[error] database.run(insertAction)
[error] ^
[error] one error found
[error] (compile:compileIncremental) Compilation failed
[error] Total time: 3 s, completed Sep 8, 2016 2:11:32 PM
您的 insertAction
returns 插入的行数,因此您应该映射到该值并检查操作是否成功:
def create(blockHeader: BlockHeader): Future[BlockHeader] = {
val insertAction = (table += blockHeader).flatMap {
case 0 => DBIO.failed(new Exception("Failed to insert `BlockHeader` object"))
case _ => DBIO.successful(blockHeader)
}
db.run(insertAction)
}
默认情况下 +=
return 受影响的行数,通常为 1。但是为了满足 create
函数的签名,您需要 return一个BlockHeader
。您可以通过简单地链接一个 return 是您的 "insert" 值的 DBIO.successful()
操作来做到这一点:
def create(blockHeader: BlockHeader): Future[BlockHeader] = {
val insertion: DBIO[BlockHeader] = (table += blockHeader).andThen(DBIO.successful(blockHeader))
database.run(insertAction)
}
andThen
在第一个动作成功后立即执行,并将 return 第二个动作的值。
不要与 returning
混淆。使用 returning
您可以更改 +=
和 ++=
return 的值。也就是说,大多数 DBMS 只允许 return 单个自动递增的主键。例如,如果 hash
是一个自动递增的值,您可以 return 像这样:
val hash = (table returning table.map(_.hash)) += blockHeader
更进一步,您还可以使用 into
:
在 BlockHeader
对象中插入该值
val blockHeaderWithHash = (table returning table.map(_.hash) into ((blockHeader, hash) => blockHeader.copy(hash = hash))) += blockHeader
我正在尝试将一个元素简单地插入到数据库中,而 table 上没有 autoinc 标志。
这是 table 定义,我定义了所有合适的映射器:
class BlockHeaderTable(tag: Tag) extends Table[BlockHeader](tag,"block_headers") {
def hash = column[DoubleSha256Digest]("hash", O.PrimaryKey)
def version = column[UInt32]("version")
def previousBlockHash = column[DoubleSha256Digest]("previous_block_hash")
def merkleRootHash = column[DoubleSha256Digest]("merkle_root_hash")
def time = column[UInt32]("time")
def nBits = column[UInt32]("n_bits")
def nonce = column[UInt32]("nonce")
def * = (hash, version, previousBlockHash, merkleRootHash, time, nBits, nonce).<>[BlockHeader,
(DoubleSha256Digest, UInt32, DoubleSha256Digest, DoubleSha256Digest, UInt32, UInt32, UInt32)](blockHeaderApply,blockHeaderUnapply)
}
我正在尝试为此 table 创建一个简单的插入函数。这是我的尝试:
override val table = TableQuery[BlockHeaderTable]
def create(blockHeader: BlockHeader): Future[BlockHeader] = {
val insertAction = table += blockHeader
database.run(insertAction)
}
我收到以下类型的错误:
chris@chris-870Z5E-880Z5E-680Z5E:~/dev/bitcoins-spv-node$ sbt compile
[info] Loading project definition from /home/chris/dev/bitcoins-spv-node/project
[info] Set current project to bitcoins-spv-node (in build file:/home/chris/dev/bitcoins-spv-node/)
[info] Compiling 1 Scala source to /home/chris/dev/bitcoins-spv-node/target/scala-2.11/classes...
[error] /home/chris/dev/bitcoins-spv-node/src/main/scala/org/bitcoins/spvnode/models/BlockHeaderDAO.scala:30: type mismatch;
[error] found : slick.profile.FixedSqlAction[Boolean,slick.dbio.NoStream,slick.dbio.Effect.Write]
[error] required: slick.dbio.DBIOAction[org.bitcoins.core.protocol.blockchain.BlockHeader,slick.dbio.NoStream,Nothing]
[error] database.run(insertAction)
[error] ^
[error] one error found
[error] (compile:compileIncremental) Compilation failed
[error] Total time: 3 s, completed Sep 8, 2016 2:11:32 PM
您的 insertAction
returns 插入的行数,因此您应该映射到该值并检查操作是否成功:
def create(blockHeader: BlockHeader): Future[BlockHeader] = {
val insertAction = (table += blockHeader).flatMap {
case 0 => DBIO.failed(new Exception("Failed to insert `BlockHeader` object"))
case _ => DBIO.successful(blockHeader)
}
db.run(insertAction)
}
默认情况下 +=
return 受影响的行数,通常为 1。但是为了满足 create
函数的签名,您需要 return一个BlockHeader
。您可以通过简单地链接一个 return 是您的 "insert" 值的 DBIO.successful()
操作来做到这一点:
def create(blockHeader: BlockHeader): Future[BlockHeader] = {
val insertion: DBIO[BlockHeader] = (table += blockHeader).andThen(DBIO.successful(blockHeader))
database.run(insertAction)
}
andThen
在第一个动作成功后立即执行,并将 return 第二个动作的值。
不要与 returning
混淆。使用 returning
您可以更改 +=
和 ++=
return 的值。也就是说,大多数 DBMS 只允许 return 单个自动递增的主键。例如,如果 hash
是一个自动递增的值,您可以 return 像这样:
val hash = (table returning table.map(_.hash)) += blockHeader
更进一步,您还可以使用 into
:
BlockHeader
对象中插入该值
val blockHeaderWithHash = (table returning table.map(_.hash) into ((blockHeader, hash) => blockHeader.copy(hash = hash))) += blockHeader