如何让 Slick create table 语句使用 InnoDB
How to get Slick create table statements to use InnoDB
我最近选择了 Slick 和 Scala,并意识到我的数据库 table 是由 Slick 使用 MYISAM 创建的,这似乎是我 MySQL 配置和 Slick 创建 table 语句不指定引擎。这一切都很好,但我想在不更改 MySQL 中的默认 table 引擎的情况下更改为 InnoDB。华而不实的文档与此事无关。是否可以在不修改 MySQL my.ini 中的默认引擎的情况下使用 Slick(在 table 创建之前)更改 table 引擎?
您可以定义引擎或通过操作语句扩展查询:
val statements: Iterator[String] = myTableQuery.schema.createStatements
val action: SqlAction[Int, NoStream, Effect] =
sqlu"#${createStatement.mkString(" ")} engine=InnoDB"
db.run(createAction)
注意 sqlu
插值器使用 #
逐字插值前缀 - 没有它,语句将被转义,导致语法错误。
查看相关文档:http://slick.lightbend.com/doc/3.2.3/schemas.html#data-definition-language
编辑:
我注意到,如果 DDL 生成多个语句(如附加 alter table...
),该方法将不起作用。在这种情况下,还有一个更不优雅的解决方案:
def createTable(ddl: profile.DDL, db: Database)(implicit ec: ExecutionContext): Future[Int] = {
val mapped = ddl.createStatements.toList map (
s => if (s.startsWith("create table")) s"$s engine=InnoDB" else s
)
mapped.foldLeft(Future.successful(1)) {
case (acc: Future[Int], s: String) =>
acc.flatMap(_ => db.run(sqlu"#$s"))
}
}
您不能使用 traverse
或 map
来创建期货,因为 alter table
取决于 table 已经存在。使用 flatMap
顺序执行。
我最近选择了 Slick 和 Scala,并意识到我的数据库 table 是由 Slick 使用 MYISAM 创建的,这似乎是我 MySQL 配置和 Slick 创建 table 语句不指定引擎。这一切都很好,但我想在不更改 MySQL 中的默认 table 引擎的情况下更改为 InnoDB。华而不实的文档与此事无关。是否可以在不修改 MySQL my.ini 中的默认引擎的情况下使用 Slick(在 table 创建之前)更改 table 引擎?
您可以定义引擎或通过操作语句扩展查询:
val statements: Iterator[String] = myTableQuery.schema.createStatements
val action: SqlAction[Int, NoStream, Effect] =
sqlu"#${createStatement.mkString(" ")} engine=InnoDB"
db.run(createAction)
注意 sqlu
插值器使用 #
逐字插值前缀 - 没有它,语句将被转义,导致语法错误。
查看相关文档:http://slick.lightbend.com/doc/3.2.3/schemas.html#data-definition-language
编辑:
我注意到,如果 DDL 生成多个语句(如附加 alter table...
),该方法将不起作用。在这种情况下,还有一个更不优雅的解决方案:
def createTable(ddl: profile.DDL, db: Database)(implicit ec: ExecutionContext): Future[Int] = {
val mapped = ddl.createStatements.toList map (
s => if (s.startsWith("create table")) s"$s engine=InnoDB" else s
)
mapped.foldLeft(Future.successful(1)) {
case (acc: Future[Int], s: String) =>
acc.flatMap(_ => db.run(sqlu"#$s"))
}
}
您不能使用 traverse
或 map
来创建期货,因为 alter table
取决于 table 已经存在。使用 flatMap
顺序执行。