我正在开发一个使用光滑的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值添加为组成复合主键的行的参数,则光滑将能够正确地确定键。
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,现在可以从数据库的模式动态生成代码模式。这个生成的模式没有解决复合主键的问题。
是否有一种方法可以使用复合主键创建灵活的codegen函数,以允许使用insertOrUpdate或更新? Codegen确实支持复合主键,但它仅用于生成以下值:
/** Primary key of TableName(database name table_name_pk) */
val pk = primaryKey("table_name_pk", (keyPart1, keyPart2))
然而,这似乎不足以使光滑能够正确识别行。如果无法使用,是否有其他方法可用于更新这些行?
答案 0 :(得分:0)
通过审查有关更新的其他帖子确定的解决方法是使用此post中的过滤器(...)。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中的某些函数。