【问题标题】:Update rows with composite primary key generated from database with slick codegen使用 slick codegen 从数据库生成的复合主键更新行
【发布时间】:2016-08-24 18:06:38
【问题描述】:

我正在开发一个使用 slick 作为数据库访问库的 scala 项目。我正在尝试使用以下定义更新有复合键的行。

class TableName(tag: Tag) extends Table[TableName](tag, "table_name"){
    def keyPart1 = column[String]("key_part_1", O.Length(100, varying = true))
    def keyPart2 = column[String]("key_part_2", O.Length(100, varying = true))
    // More columns defined
    def pk = primaryKey("t_composite_pk", (keyPart1, keyPart2))
    def * (keyPart1, keyPart2, ..more columns..) <> (TableNameRow.tupled, TableNameRow)
}

使用 JdbcActionComponent 中的 insertOrUpdate 或 update 方法将无法插入或更新值。光滑的known issue 带有复合主键,这将阻止这些方法正常运行,因为它无法确定它应该与哪个标识符相关。但是,有一种解决方法。如果您将 O.PrimaryKey 值添加为构成复合主键的行的参数,那么 slick 将能够正确确定键。

class TableName(tag: Tag) extends Table[TableName](tag, "table_name"){
    def keyPart1 = column[String]("key_part_1", O.Length(100, varying = true), O.PrimaryKey)
    def keyPart2 = column[String]("key_part_2", O.Length(100, varying = true), O.PrimaryKey)
    // More columns defined
    def pk = primaryKey("t_composite_pk", (keyPart1, keyPart2))
    def * (keyPart1, keyPart2, ..more columns..) <> (TableNameRow.tupled, TableNameRow)
}

现在已迁移项目以使用 slick codegen,并且代码架构现在是从数据库架构动态生成的。此生成的架构不具备复合主键的解决方法。

有没有一种方法可以使用复合主键来制作流畅的代码生成功能,以允许使用 insertOrUpdate 或更新? Codegen 确实对复合主键有一些支持,但它只是用于生成以下值:

/** Primary key of TableName(database name table_name_pk) */
val pk = primaryKey("table_name_pk", (keyPart1, keyPart2)) 

然而,这似乎不足以让 slick 能够正确识别行。如果这无法正常工作,是否有其他方法可用于更新这些行?

【问题讨论】:

  • 策略是使用 codegen 并且不提交生成表 scala 定义,因此不能修改生成的文件

标签: scala slick slick-3.0


【解决方案1】:

通过查看其他有关更新的帖子确定的解决方法是使用来自 this post 的 filter(...).update(...)。可以使用以下方式进行更新:

// Where the following was defined by the codegen
/** Collection-like TableQuery object for table TableName*/
lazy val TableName = new TableQuery(tag => new TableName(tag))

// We can then filter on the primary key values
def updateMethod(row: TableNameRow) = 
    TableName
       .filter(x => x.keyPart1 === row.keyPart1 && x.keyPart2 === row.keyPart2)
       .update(row)

如果我们通过过滤器模拟键,它可以应用于允许使用组合键更新行。但是,这是一种解决方法,不允许使用 JdbcActionComponent 中的某些函数。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-07-22
    • 1970-01-01
    • 2017-02-28
    • 1970-01-01
    • 2014-06-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多