2016-12-22 6 views
1

이 테이블 정의는 null 입력 가능 열을 가짐으로써 String 대신 Option [String]을 사용해야한다는 것을 알게되었습니다. 그게 내가 만든 유일한 변화 였고 지금은 내 코드가 어떻게 생겼는지입니다.Null 허용 열이있는 매끄러운 테이블 정의는 어떻게 작성합니까?

class RespondentTableDef(tag: Tag) extends Table[Respondent](tag, "respondent") { 

    def id = column[Long]("id", O.PrimaryKey) 
    def uuid = column[String]("uuid") 
    def version = column[Long]("version") 
    def task = column[Long]("task") 
    def firstName = column[Option[String]]("first_name") 
    def lastName = column[Option[String]]("last_name") 
    def ageGroup = column[Option[String]]("age_group") 
    def incomeLevel = column[Option[String]]("income_level") 
    def employmentStatus = column[Option[String]]("employment_status") 
    def maritalStatus = column[Option[String]]("marital_status") 
    def housingStatus = column[Option[String]]("housing_status") 
    def educationStatus = column[Option[String]]("education_status") 
    def gender = column[Option[String]]("gender") 

    override def * = 
    (id, uuid, version, task, firstName, lastName, ageGroup, incomeLevel, employmentStatus, maritalStatus, housingStatus, educationStatus, gender) <> (Respondent.tupled, Respondent.unapply) 
} 

컴파일 할 때이 오류가 발생합니다.

[error] /Users/roy/adivinate/survey2/app/model/Respondent.scala:45: No matching Shape found. 
[error] Slick does not know how to map the given types. 
[error] Possible causes: T in Table[T] does not match your * projection. Or you use an unsupported type in a Query (e.g. scala List). 
[error] Required level: slick.lifted.FlatShapeLevel 
[error]  Source type: (slick.lifted.Rep[Long], slick.lifted.Rep[String], slick.lifted.Rep[Long], slick.lifted.Rep[Long], slick.lifted.Rep[Option[String]], slick.lifted.Rep[Option[String]], slick.lifted.Rep[Option[String]], slick.lifted.Rep[Option[String]], slick.lifted.Rep[Option[String]], slick.lifted.Rep[Option[String]], slick.lifted.Rep[Option[String]], slick.lifted.Rep[Option[String]], slick.lifted.Rep[Option[String]]) 
[error] Unpacked type: (Long, String, Long, Long, String, String, String, String, String, String, String, String, String) 
[error]  Packed type: Any 
[error]  (id, uuid, version, task, firstName, lastName, ageGroup, incomeLevel, employmentStatus, maritalStatus, housingStatus, educationStatus, gender) <> (Respondent.tupled, Respondent.unapply) 
[error]                                     ^
[error] one error found 
[error] (compile:compileIncremental) Compilation failed 
[error] Total time: 5 s, completed Dec 21, 2016 8:53:17 PM 

답변

1

기본적으로 사례 클래스는이 필드를 선택적으로 지정해야합니다. 예 : 대신에 (귀하의 경우 클래스) : firstName: StringfirstName: Option[String] 있어야합니다.

1

해당 열이 널

방금로 선언 널 (NULL) 뭔가를 확인하려면 예를 들어

case class Foo(name: String, rating: Option[Int]) 

class Foos(tag: Tag) extends Table[Foo](tag, "foos") { 
    def name = column[String]("name") //name is not null 
    def rating = column[Option[Int]]("rating") //rating is nullable 
    def * = (name, rating) <> (Foo.tupled, Foo.unapply) 
} 

이것을 이해 수 있습니다 있는지 확인하는 Option[T] 대신 T으로 모델 클래스에 필드를 선언 Option 필드와 그것을 매끄러운 thats 이해할 것이며 nullable로 해당 필드를 사용하여 SQL을 생성합니다.

위의 디자인은 스칼라 옵션 디자인으로 매끄럽고 건강합니다. 스칼라의 옵션은 sql의 Nullable로 직접 변환됩니다. 슬릭

의 이전 버전에서

당신은 특정 컬럼이 명시 적으로 열 선언에 O.NotNull을 전달하여 null가 아닌,하지만이 약은

1

하지 마십시오의 새 버전에 필요하지 않은 이야기했다 옵션을 사용하여 열을 정의하십시오. Option [String] 컬럼이 있다면 여전히 String이어야합니다.

def firstName = column[Option[String]]("first_name") //Bad 
def firstName = column[String]("first_name") //Good 

select (def *) use를 정의 할 때? 당신이 열 정의에`Option`을 사용하지 말아야하는 이유

def updateExistingName(name : String) : DBIO[Int] = 
{ 
    map(_.firstName).update(name) 
} 

def updateOptionName(nameCanBeNone: Option[String]) : DBIO[Int] = 
{ 
    map(_.firstName.?).update(nameCanBeNone) 
} 
+3

당신이 공유 할 수 없습니다 : 당신이 (TableQuery에서) 업데이트 할 경우에도 옵션을

override def * = (id, uuid, version, task, firstName.?, lastName.?, ageGroup.?, incomeLevel.?, employmentStatus.?, maritalStatus.?, housingStatus.?, educationStatus.?, gender.?) <> (Respondent.tupled, Respondent.unapply) 

을 정의? –

+2

열이 Null 인 경우 Option을 사용해야합니다. –