5

I'm using Slick 2 code generator in my Scala/Play application to generate table classes of my PostgreSQL database. Some of the fields are JSON type though and they are turned into a String by the generator. I was wondering if I can somehow use slick-pg plugin to make the generator recognize Postgres JSON type?

I've tried to extend slick.driver.PostgresDriver directly in Build.scala:

import slick.driver.PostgresDriver
import com.github.tminglei.slickpg._

trait MyPostgresDriver extends PostgresDriver
                          with PgArraySupport
                          with PgDateSupport
                          with PgRangeSupport
                          with PgHStoreSupport
                          with PgPlayJsonSupport
                          with PgSearchSupport
                          with PgPostGISSupport {

  override val Implicit = new ImplicitsPlus {}
  override val simple = new SimpleQLPlus {}

  trait ImplicitsPlus extends Implicits
                        with ArrayImplicits
                        with DateTimeImplicits
                        with RangeImplicits
                        with HStoreImplicits
                        with JsonImplicits
                        with SearchImplicits
                        with PostGISImplicits

  trait SimpleQLPlus extends SimpleQL
                        with ImplicitsPlus
                        with SearchAssistants
                        with PostGISAssistants
}

object MyPostgresDriver extends MyPostgresDriver

But I don't know how to use it with the code generator routine instead of the standard driver:

SourceCodeGenerator.main(
    Array(
        "scala.slick.driver.PostgresDriver", //how do I use MyPostgresDriver here?
        "org.postgresql.Driver", 
        "jdbc:postgresql://localhost:5432/db?user=root&password=root", 
        "app", 
        "db"
    )
)       
Caballero
  • 9,738
  • 18
  • 89
  • 151

2 Answers2

4

You can't make the generator pick up the type this way. It (or rather the Slick code that reverse engineers the Model from the database schema) currently only detects a hand full of types and simply assumes String for all other ones. This will be improved in the future. In order to make it use a different type for a column you have to customize the generator. The corresponding Slick documentation example actually shows how to customize the type:

http://slick.typesafe.com/doc/2.0.0/code-generation.html#customization

cvogt
  • 11,125
  • 27
  • 45
  • 1
    In this example you've linked to - is it possible instead of targeting column name, target column type? Something like this: `override def rawType = if (model.type == "SOME_SPECIAL_COLUMN_TYPE") "MyCustomType" else super.rawType`. – Caballero Mar 17 '14 at 06:05
  • The model only contains the type Slick mapped to, which would probably be String in this case. I don't think that is what you want. You either need to go by name or alternatively you can request the schema meta data via JDBC. You can use this Slick helper: http://slick.typesafe.com/doc/2.0.0/api/index.html#scala.slick.jdbc.meta.MColumn$ – cvogt Mar 17 '14 at 14:56
  • 1
    @cvogt I'm facing the same issue, where `SERIAL` is being mapped as an `Int` when it should be `Long`. Doing it by column name is far from ideal and would be very iffy. Can you provide an example using the JDBC metadata? – Akos Krivachy Mar 18 '14 at 21:50
  • Slick comes with a wrapper for jdbc's DatabaseMetaData api. See http://slick.typesafe.com/doc/2.0.1/api/#scala.slick.jdbc.meta.package Here are some places using it: https://github.com/slick/slick/blob/master/slick-testkit/src/test/scala/scala/slick/test/jdbc/MetaTest.scala https://github.com/slick/slick/blob/9145c8162d3e5028e890222b28ca3d4cfe20170c/src/main/scala/scala/slick/driver/JdbcProfile.scala#L60 https://github.com/slick/slick/blob/master/src/main/scala/scala/slick/jdbc/meta/package.scala – cvogt Apr 06 '14 at 11:40
0

You can also define a function to access to the json tree directly

val jsonSQL=
SimpleFunction.binary[Option[String],String,Option[String]]("json_extract_path_text")
arivero
  • 781
  • 1
  • 9
  • 23