Slick 3 - 未生成ForeignKeys

时间:2015-05-15 19:15:41

标签: mysql scala persistence slick play-slick

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

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

并且配置文件类仅包含id字段。 Identifiable提供了id-property。

我正在使用Slick 3和MySQL。

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

更新

这里有相关的陈述:

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)更新NO ACTION on delete NO ACTION

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

alter table NAME添加约束version_fk外键(versionId)引用VERSIONid)更新NO ACTION on delete NO ACTION

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

alter table PHONENUMBER添加约束version_fk外键(versionId)引用VERSIONid)更新NO ACTION on delete NO ACTION

alter table PHONENUMBERS_VIEWS添加约束phoneNumber_fk外键(phoneNumber)引用PHONENUMBERid)更新NO ACTION on delete NO ACTION alter table PHONENUMBERS_VIEWS在更新时添加约束view_fk外键(view)引用VIEWid)删除时无行动

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

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

编辑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 个答案:

答案 0 :(得分:2)

  

“对于名称,会生成对配置文件的foreignKey,而不是PhoneNumbers。   为什么?似乎没有区别?“

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

您为 $query=mysql_query("SELECT * FROM emptype WHERE typename = '$emptype' AND typedesc='$typedesc') or die(mysql_error()); if (mysql_num_rows($query)<=0) { $query=mysql_query("insert into emptype(typename,typedesc)values('$emptype','$typedesc')")or die("<script>alert('Error');</script>"); } Names.profileFk使用了相同的外键名称(“profile_fk”)。 MySQL外键名称必须是唯一的。

我建议将“profile_fk”替换为“name_profile_fk”和“phonenumber_profile_fk”。

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

PhoneNumbers.profileFk

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

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