Slick 3 - 不生成外键

Slick 3 - ForeignKeys are not generated

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

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)
}

并且配置文件 class 仅包含一个 id 字段。可识别提供id-属性.

我在 MySQL 中使用 Slick 3。

对于名称,会生成配置文件的外键,对于电话号码则不会。为什么?好像没什么区别?

更新:

此处相关声明:

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

完整输出:

创建 table PROFILEid 整数不为空 AUTO_INCREMENT 主键,userId 整数不为空)

create table VERSION (id INTEGER NOT NULL AUTO_INCREMENT PRIMARY KEY,timestamp INTEGER NOT NULL,vector INTEGER NOT NULL )

create table NAME (id INTEGER NOT NULL AUTO_INCREMENT PRIMARY KEY,firstName TEXT NOT NULL,lastName TEXT NOT NULL ,profileId 整数不为空,versionId 整数不为空)

创建 table PHONENUMBER (id INTEGER NOT NULL AUTO_INCREMENT PRIMARY KEY,number TEXT NOT NULL,kind TEXT NOT NULL ,profileId 整数不为空,versionId 整数不为空)

创建tableVIEWid整数不为空AUTO_INCREMENT主键) 创建 table PHONENUMBERS_VIEWSphoneNumber 整数不为空,view 整数不为空)

创建 table CREDENTIALS (id INTEGER NOT NULL AUTO_INCREMENT PRIMARY KEY,username TEXT NOT NULL,password TEXT NOT NULL ,userId 整数不为空)

创建tableUSERid整数不为空AUTO_INCREMENT主键)

创建 table API_KEY (id INTEGER NOT NULL AUTO_INCREMENT PRIMARY KEY,token TEXT NOT NULL,deviceId TEXT NOT NULL ,credentialsId 整数不为空)

更改 table PROFILE 添加约束 user_fk 外键 (userId) 引用 USER(id) 更新 NO ACTION删除无操作

更改 table NAME 添加约束 profile_fk 外键 (profileId) 引用 PROFILE(id) 更新 NO ACTION删除级联

更改 table NAME 添加约束 version_fk 外键 (versionId) 引用 VERSION(id) 更新 NO ACTION删除无操作

更改table PHONENUMBER 添加约束profile_fk 外键(profileId) 引用PROFILE(id) 更新无操作删除级联

更改 table PHONENUMBER 添加约束 version_fk 外键 (versionId) 引用 VERSION(id) 更新 NO ACTION删除无操作

更改 table PHONENUMBERS_VIEWS 添加约束 phoneNumber_fk 外键 (phoneNumber) 引用 PHONENUMBER(id) 更新 NO ACTION删除 NO ACTION alter table PHONENUMBERS_VIEWS add constraint view_fk foreign key(view) references VIEW(id) on update NO ACTION on delete NO ACTION

更改 table CREDENTIALS 添加约束 user_fk 外键 (userId) 引用 USER(id) 更新 NO ACTION删除无操作

更改 table API_KEY 添加约束 credentials_fk 外键 (credentialsId) 引用 CREDENTIALS(id) 更新 NO ACTION删除无操作

` 符号因为降价而被隐藏,但在原始输出中

编辑 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)

"For Names a foreignKey to Profiles is generated, for PhoneNumbers not. Why? There seems to be no difference?"

我认为缺少差异是这里的问题。

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

我建议将 "profile_fk" 替换为 "name_profile_fk" 和 "phonenumber_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

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

如果您没有看到异常,可能是您的应用程序在您将来执行 returns 之前终止。您可以通过在 SlickDB().run 命令周围放置一个 await 来测试它。例如,

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