首页 文章

Slick 3 - 不生成ForeignKeys

提问于
浏览
1

我似乎无法找到这个奇怪的错误的解决方案:

class Names(tag: Tag) extends Table[Name](tag, "NAME") with Identifiable[Name]{
  def firstName = column[String]("firstName")
  def lastName = column[String]("lastName")
  def profileId = column[Int]("profileId")
  def * = (id.?, firstName, lastName, profileId) <> ((Name.apply _).tupled, Name.unapply)
  def profileFk = foreignKey("profile_fk", profileId, TableQuery[Profiles])(_.id, onDelete=ForeignKeyAction.Cascade)
}

class PhoneNumbers(tag: Tag) extends Table[PhoneNumber](tag, "PHONENUMBER") with Identifiable[PhoneNumber] {
  def number = column[String]("number")
  def kind = column[String]("kind")
  def profileId = column[Int]("profileId")
  def * = (id.?, number, kind, profileId) <> ((PhoneNumber.apply _).tupled, PhoneNumber.unapply)
  def profileFk = foreignKey("profile_fk", profileId, TableQuery[Profiles])(_.id, onDelete=ForeignKeyAction.Cascade)
}

而profile类只包含一个id字段 . Identifiable提供id属性 .

我正在使用Slick 3和MySQL .

对于Names,将生成一个foreignKey to Profiles,而不是PhoneNumbers . 为什么?似乎没有什么区别?

Update:

这里有相关的陈述:

create table `PHONENUMBER` (`id` INTEGER NOT NULL AUTO_INCREMENT PRIMARY KEY,`number` TEXT NOT NULL,`kind` TEXT NOT NULL,`profileId` INTEGER NOT NULL)

和:

alter table `PHONENUMBER` add constraint `profile_fk` foreign key(`profileId`) references `PROFILE`(`id`) on update NO ACTION on delete CASCADE

完成输出:

create table PROFILEid INTEGER NOT NULL AUTO_INCREMENT PRIMARY KEY, userId INTEGER NOT NULL)

create table VERSIONid INTEGER NOT NULL AUTO_INCREMENT PRIMARY KEY, timestamp INTEGER NOT NULL, vector INTEGER NOT NULL)

create table NAMEid INTEGER NOT NULL AUTO_INCREMENT PRIMARY KEY, firstName TEXT NOT NULL, lastName TEXT NOT NULL, profileId INTEGER NOT NULL, versionId INTEGER NOT NULL)

create table PHONENUMBERid INTEGER NOT NULL AUTO_INCREMENT PRIMARY KEY, number TEXT NOT NULL, kind TEXT NOT NULL, profileId INTEGER NOT NULL, versionId INTEGER NOT NULL)

create table VIEWid INTEGER NOT NULL AUTO_INCREMENT PRIMARY KEY)create table PHONENUMBERS_VIEWSphoneNumber INTEGER NOT NULL, view INTEGER NOT NULL)

create table CREDENTIALSid INTEGER NOT NULL AUTO_INCREMENT PRIMARY KEY, username TEXT NOT NULL, password TEXT NOT NULL, userId INTEGER NOT NULL)

create table USERid INTEGER NOT NULL AUTO_INCREMENT PRIMARY KEY)

create table API_KEYid INTEGER NOT NULL AUTO_INCREMENT PRIMARY KEY, token TEXT NOT NULL, deviceId TEXT NOT NULL, credentialsId INTEGER NOT NULL)

alter table PROFILE 添加约束 user_fk 外键( userId )引用 USERid )更新时无操作删除无操作

alter table NAME 添加约束 profile_fk 外键( profileId )引用 PROFILEid )更新NO ACTION对删除CASCADE

alter table NAME 添加约束 version_fk 外键( versionId )引用 VERSIONid )更新时无操作删除无操作

alter table PHONENUMBER 添加约束 profile_fk 外键( profileId )引用 PROFILEid )更新NO ACTION对删除CASCADE

alter table PHONENUMBER 添加约束 version_fk 外键( versionId )引用 VERSIONid )更新时无操作删除无操作

alter table PHONENUMBERS_VIEWS 添加约束 phoneNumber_fk 外键( phoneNumber )引用 PHONENUMBERid )更新NO ACTION on删除NO ACTION alter table PHONENUMBERS_VIEWS add constraint view_fk 外键( view )引用 VIEWid )更新时没有操作删除NO ACTION

alter table CREDENTIALS 添加约束 user_fk 外键( userId )引用 USERid )更新NO ACTION on delete NO ACTION

alter table API_KEY 添加约束 credentials_fk 外键( credentialsId )引用 CREDENTIALSid )更新NO ACTION on delete NO ACTION

`符号由于降价而隐藏,但在原始输出中

EDIT 2

val profiles = TableQuery[Profiles]
val names = TableQuery[Names]
val phoneNumbers = TableQuery[PhoneNumbers]
val views = TableQuery[Views]
val phoneNumbersToViews = TableQuery[PhoneNumbersToViews]
val users = TableQuery[Users]
val credentials = TableQuery[CredentialsSchema]
val apiKeys = TableQuery[ApiKeys]
val versions = TableQuery[Versions]

val schema = profiles.schema ++
  versions.schema ++
  names.schema ++
  phoneNumbers.schema ++
  views.schema ++
  phoneNumbersToViews.schema ++
  credentials.schema ++
  users.schema ++
  apiKeys.schema

SlickDB().run(DBIO.seq(
  schema.create
))

schema.createStatements.foreach(println)

1 回答

  • 2

    “对于Names,生成了一个foreignKey to Profiles,对于PhoneNumbers没有 . 为什么?似乎没有区别?”

    我认为缺乏差异是这里的问题 .

    您已为 Names.profileFkPhoneNumbers.profileFk 使用了相同的外键名称("profile_fk") . MySQL外键名称必须是唯一的 .

    我建议用“name_profile_fk”和“phonenumber_profile_fk”替换“profile_fk” .

    但是,你应该看到一个例外 . 您包含的第一个alter table语句......

    alter table NAME add constraint profile_fk foreign key(profileId) references PROFILE(id) on update NO ACTION on delete CASCADE
    

    ......应该运行正常,但第二......

    alter table PHONENUMBER add constraint profile_fk foreign key(profileId) references PROFILE(id) on update NO ACTION on delete CASCADE
    

    ......是应该有例外的地方 .

    如果您没有看到异常,则可能是您的应用程序在将来执行返回之前终止 . 您可以通过在 SlickDB().run 命令周围等待来测试它 . 例如 . ,

    import scala.concurrent.Await
    import scala.concurrent.duration._
    Await.result(
      SlickDB().run(DBIO.seq(schema.create))
      , 10 seconds)
    

相关问题