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 PROFILE
(id
整数不为空 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
整数不为空)
创建tableVIEW
(id
整数不为空AUTO_INCREMENT主键)
创建 table PHONENUMBERS_VIEWS
(phoneNumber
整数不为空,view
整数不为空)
创建 table CREDENTIALS
(id
INTEGER NOT NULL AUTO_INCREMENT PRIMARY KEY,username
TEXT NOT NULL,password
TEXT NOT NULL ,userId
整数不为空)
创建tableUSER
(id
整数不为空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.profileFk
和 PhoneNumbers.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)
我似乎找不到解决这个奇怪错误的方法:
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 PROFILE
(id
整数不为空 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
整数不为空)
创建tableVIEW
(id
整数不为空AUTO_INCREMENT主键)
创建 table PHONENUMBERS_VIEWS
(phoneNumber
整数不为空,view
整数不为空)
创建 table CREDENTIALS
(id
INTEGER NOT NULL AUTO_INCREMENT PRIMARY KEY,username
TEXT NOT NULL,password
TEXT NOT NULL ,userId
整数不为空)
创建tableUSER
(id
整数不为空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.profileFk
和 PhoneNumbers.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)