Access database column names from a table?

Let's say I have a table :

object Suppliers extends Table[(Int, String, String, String)]("SUPPLIERS") { def id = column[Int]("SUP_ID", O.PrimaryKey) def name = column[String]("SUP_NAME") def state = column[String]("STATE") def zip = column[String]("ZIP") def * = id ~ name ~ state ~ zip } 

Table database name

You can access the table database name by going to: Suppliers.tableName
This is supported by Scaladoc on AbstractTable .

For example, the above table name is the table SUPPLIERS.

Column Column Names

Viewing AbstractTable , getLinearizedNodes and indexes looked promising. However, column names are not present in string representations.

I assume that * means all columns that usually interest me. * is a MappedProjection that has this signature:

 final case class MappedProjection[T, P <: Product]( child: Node, f: (P) β‡’ T, g: (T) β‡’ Option[P])(proj: Projection[P]) extends ColumnBase[T] with UnaryNode with Product with Serializable 

*.getLinearizedNodes contains a huge sequence of numbers, and I realized that at this point I just do a rough check of all the API elements to possibly search for the column names in String.

Has anyone else encountered this problem before, or can someone better understand how MappedProjection works?

+7
scala slick
source share
3 answers

This requires you to rely on internal Slick elements that can vary between versions, but it is possible. Here's how it works for Slick 1.0.1: you need to go through FieldSymbol . You can then extract the information you need, as columnInfo(driver: JdbcDriver, column: FieldSymbol): ColumnInfo .

To get FieldSymbol from Column , you can use fieldSym(node: Node): Option[FieldSymbol] and fieldSym(column: Column[_]): FieldSymbol .

+3
source share

To get the (qualified) column names, you can simply do the following:

 Suppliers.id.toString Suppliers.name.toString Suppliers.state.toString Suppliers.zip.toString 

It is not explicitly stated that toString will give the column name, so your question is valid.


Now, if you want to get all the column names programmatically, it's a little more complicated. You can try using reflection to get all methods that return Column[_] and call toString on them, but that would not be elegant. Or you can hack a bit and get the SQL select * statement from a query like this:

 val selectStatement = DB withSession { Query(Suppliers).selectStatement } 

And then parse our column names.

This is the best I could do. If someone knows the best way, then please share - I'm also interested;)

+2
source share

The code is based on the Lightbend Activator "slick-http-app".

slick version: 3.1.1

Added this method to BaseDal:

 def getColumns(): mutable.Map[String, Type] = { val columns = mutable.Map.empty[String, Type] def selectType(t: Any): Option[Any] = t match { case t: TableExpansion => Some(t.columns) case t: Select => Some(t.field) case _ => None } def selectArray(t:Any): Option[ConstArray[Node]] = t match { case t: TypeMapping => Some(t.child.children) case _ => None } def selectFieldSymbol(t:Any): Option[FieldSymbol] = t match { case t: FieldSymbol => Some(t) case _ => None } val t = selectType(tableQ.toNode) val c = selectArray(t.get) for (se <- c.get) { val col = selectType(se) val fs = selectFieldSymbol(col.get) columns += (fs.get.name -> fs.get.tpe) } columns } 

this method gets the column names (real names in the database) + types form TableQ

import used:

  import slick.ast._ import slick.util.ConstArray 
+1
source share

All Articles