Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Creating a composition Primary Key using Scala Slick

Tags:

scala

slick

I'm trying to use two column's as my primary key for a Scala Slick table. Here is how my table is defined:

class NbaPlayerBoxScoreTable(tag : Tag) extends Table[NbaPlayerBoxScore](tag, "player_box_scores") {
  import com.suredbits.core.db.ColumnMappers._
  private val gameTable : TableQuery[NbaGameTable] = TableQuery[NbaGameTable]
  private val playerTable  : TableQuery[NbaPlayerTable] = TableQuery[NbaPlayerTable]
  def playerId = column[Long]("player_id", O.PrimaryKey)
  def gameId = column[Long]("game_id", O.PrimaryKey)
  def lastUpdated = column[DateTime]("last_updated")
  def min = column[String]("min")
  def fgm = column[Int]("fgm")
  def fga = column[Int]("fga")
  def tpm = column[Int]("tpm")
  def tpa = column[Int]("tpa")
  def ftm = column[Int]("ftm")
  def fta = column[Int]("fta")
  def plusminus = column[Int]("plusminus")
  def off = column[Int]("off")
  def deff = column[Int]("def")
  def tot = column[Int]("tot")
  def ast = column[Int]("ast")
  def pf = column[Int]("pf")
  def st = column[Int]("st")
  def to = column[Int]("to")
  def bs = column[Int]("bs")
  def ba = column[Int]("ba")
  def pts = column[Int]("pts")

  def game = foreignKey("game_fk",gameId, gameTable)(_.gameId)
  def player = foreignKey("player_id",playerId, playerTable)(_.playerId)

  def * = (playerId, gameId, lastUpdated, min,
    fgm,fga,tpm, tpa,ftm,fta,plusminus,off,deff,tot,ast,pf,st,to,bs,ba,pts) <> (NbaPlayerBoxScore.tupled, NbaPlayerBoxScore.unapply _)

}

You can see that I want a combination of playerId and gameId to be my composition primary key. When I try to create my table I get the following error

[error] (run-main-0) org.postgresql.util.PSQLException: ERROR: multiple primary keys for table "player_box_scores" are not allowed
[error]   Position: 101
org.postgresql.util.PSQLException: ERROR: multiple primary keys for table "player_box_scores" are not allowed
  Position: 101
    at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2157)
    at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1886)
    at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:255)
    at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:555)
    at org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java:417)
    at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:410)
    at org.apache.commons.dbcp.DelegatingPreparedStatement.execute(DelegatingPreparedStatement.java:172)
    at org.apache.commons.dbcp.DelegatingPreparedStatement.execute(DelegatingPreparedStatement.java:172)
    at scala.slick.driver.JdbcInvokerComponent$DDLInvoker$$anonfun$create$1$$anonfun$apply$mcV$sp$1$$anonfun$apply$1.apply(JdbcInvokerComponent.scala:50)
    at scala.slick.driver.JdbcInvokerComponent$DDLInvoker$$anonfun$create$1$$anonfun$apply$mcV$sp$1$$anonfun$apply$1.apply(JdbcInvokerComponent.scala:50)
    at scala.slick.jdbc.JdbcBackend$SessionDef$class.withPreparedStatement(JdbcBackend.scala:191)
    at scala.slick.jdbc.JdbcBackend$BaseSession.withPreparedStatement(JdbcBackend.scala:389)
    at scala.slick.driver.JdbcInvokerComponent$DDLInvoker$$anonfun$create$1$$anonfun$apply$mcV$sp$1.apply(JdbcInvokerComponent.scala:50)
    at scala.slick.driver.JdbcInvokerComponent$DDLInvoker$$anonfun$create$1$$anonfun$apply$mcV$sp$1.apply(JdbcInvokerComponent.scala:49)
    at scala.collection.Iterator$class.foreach(Iterator.scala:743)
    at scala.collection.Iterator$JoinIterator.foreach(Iterator.scala:191)
    at scala.slick.driver.JdbcInvokerComponent$DDLInvoker$$anonfun$create$1.apply$mcV$sp(JdbcInvokerComponent.scala:49)
    at scala.slick.driver.JdbcInvokerComponent$DDLInvoker$$anonfun$create$1.apply(JdbcInvokerComponent.scala:49)
    at scala.slick.driver.JdbcInvokerComponent$DDLInvoker$$anonfun$create$1.apply(JdbcInvokerComponent.scala:49)
    at scala.slick.jdbc.JdbcBackend$BaseSession.withTransaction(JdbcBackend.scala:426)
    at scala.slick.driver.JdbcInvokerComponent$DDLInvoker.create(JdbcInvokerComponent.scala:48)
    at com.suredbits.core.db.DbManagement$$anonfun$createTable$1.apply(DbManagement.scala:33)
    at com.suredbits.core.db.DbManagement$$anonfun$createTable$1.apply(DbManagement.scala:27)
    at scala.slick.backend.DatabaseComponent$DatabaseDef$class.withSession(DatabaseComponent.scala:34)
    at scala.slick.jdbc.JdbcBackend$DatabaseFactoryDef$$anon$3.withSession(JdbcBackend.scala:46)
    at com.suredbits.core.db.DbManagement$class.createTable(DbManagement.scala:27)
    at io.extrapoint.nbaapi.Main$.createTable(Main.scala:14)
    at io.extrapoint.nbaapi.db.NbaApiDbManagement$class.createNbaPlayerBoxScoreTable(NbaApiDbManagement.scala:39)
    at io.extrapoint.nbaapi.Main$.createNbaPlayerBoxScoreTable(Main.scala:14)
    at io.extrapoint.nbaapi.Main$.createBoxScoresForFinishedGames(Main.scala:64)
    at io.extrapoint.nbaapi.Main$.delayedEndpoint$io$extrapoint$nbaapi$Main$1(Main.scala:85)
    at io.extrapoint.nbaapi.Main$delayedInit$body.apply(Main.scala:14)
    at scala.Function0$class.apply$mcV$sp(Function0.scala:40)
    at scala.runtime.AbstractFunction0.apply$mcV$sp(AbstractFunction0.scala:12)
    at scala.App$$anonfun$main$1.apply(App.scala:76)
    at scala.App$$anonfun$main$1.apply(App.scala:76)
    at scala.collection.immutable.List.foreach(List.scala:381)
    at scala.collection.generic.TraversableForwarder$class.foreach(TraversableForwarder.scala:35)
    at scala.App$class.main(App.scala:76)
    at io.extrapoint.nbaapi.Main$.main(Main.scala:14)
    at io.extrapoint.nbaapi.Main.main(Main.scala)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)

Is this possible using Scala slick 2.1.0?

like image 685
Chris Stewart Avatar asked Nov 14 '15 02:11

Chris Stewart


People also ask

How do you make a composite primary key?

A Composite Primary Key is created by combining two or more columns in a table that can be used to uniquely identify each row in the table when the columns are combined, but it does not guarantee uniqueness when taken individually, or it can also be understood as a primary key created by combining two or more ...

Can you have a composite primary key?

When over one column or field in a table are combined to achieve the task of uniquely identifying row values, then that composite key can be either a primary or a candidate key of that table.

What is composite primary key with example?

A primary key having two or more attributes is called composite key. It is a combination of two or more columns. Above, our composite keys are StudentID and StudentEnrollNo. The table has two attributes as primary key.

What is the difference between primary key and composite?

While a primary key and a composite key might do the same things, the primary key will consist of one column, where the composite key will consist of two or more columns. The relationship between a primary key and a foreign key is quite different.


1 Answers

Maybe you can try using a primaryKey:

class A(tag: Tag) extends Table[(Int, Int)](tag, "a") {
  def k1 = column[Int]("k1")
  def k2 = column[Int]("k2")
  def * = (k1, k2)
  def pk = primaryKey("pk_a", (k1, k2))
  // compiles to SQL:
  //   alter table "a" add constraint "pk_a" primary key("k1","k2")
}
like image 100
余杰水 Avatar answered Nov 03 '22 00:11

余杰水