Slick-based (Scala) Flyway Migrations
One of the features I really like about Flyway is the ability to have Java-based migrations.
But how would one go about using Slick inside a Flyway Java-migration?
Particularly: how does one get hold of a Slick “Session” from one java.sql Connection?
The trick is in using Slick’s “UnmanagedSession“…
Here I want to share with you a trait that can be used to have first-class Slick Flyway migrations:
package db.migration
import org.flywaydb.core.api.migration.jdbc.JdbcMigration
import scala.slick.jdbc.UnmanagedSession
import scala.slick.driver.JdbcDriver.simple._
import java.sql.Connection
/**
* By including this trait in your Flyway JdbcMigration, you only
* need to provide an implementation for this the slick_migrate
* method, which accepts a Slick session.
*
* Given that Session, you can perform any Slick operation, like
* creating or modifying a table, populating the database, etc.
*
*/
trait SlickMigration { self: JdbcMigration =>
// Implement this in your subclass
def slick_migrate(implicit session: Session)
override final def migrate(conn: Connection) {
val session = new UnmanagedSession(conn)
try {
session.withTransaction {
slick_migrate(session)
}
} finally {
session.close()
}
}
}
Once you have this in place, you can write a Slick-based migration like this:
package db.migration.default
import org.flywaydb.core.api.migration.jdbc.JdbcMigration
import scala.slick.driver.JdbcDriver.simple._
import db.migration.SlickMigration
class V1__001_CreateMoviesTable extends JdbcMigration with SlickMigration {
override def slick_migrate(implicit session: Session) {
class Movies(tag: Tag) extends Table[(Option[Int], String, Int)](tag, "MOVIES") {
def id = column[Int]("ID", O.PrimaryKey, O.AutoInc)
def title = column[String]("TITLE")
def year = column[Int]("YEAR")
def * = (id.?, title, year)
}
val movies = TableQuery[Movies]
session.withTransaction {
movies.ddl.create
}
}
}
Advantages:
- One can create tables, and manipulate data in an DB-agnostic way
- One has the full power of Slick / Scala
Disadvantages:
- Slick is not suited for table or column alterations. For this, other approaches should be sought.
Happy Scala / Slicking!