2015-05-02 125 views
2

我對Haskell相當陌生,現在一直在嘗試使用yesod大約一週。我一直試圖連接到在sqlite中有一個複合主鍵的現有數據庫。我設法讓代碼與Database.Persist.Sqlite一起作爲獨立應用程序使用。Yesod中的複合主鍵

以下是使用persistent-sqlite作爲獨立應用程序工作的代碼。

{-# LANGUAGE EmptyDataDecls    #-} 
{-# LANGUAGE FlexibleContexts   #-} 
{-# LANGUAGE GADTs      #-} 
{-# LANGUAGE GeneralizedNewtypeDeriving #-} 
{-# LANGUAGE MultiParamTypeClasses  #-} 
{-# LANGUAGE OverloadedStrings   #-} 
{-# LANGUAGE QuasiQuotes    #-} 
{-# LANGUAGE TemplateHaskell   #-} 
{-# LANGUAGE TypeFamilies    #-} 
{-# LANGUAGE FlexibleInstances #-} 
{-# LANGUAGE DeriveGeneriC#-} 
import   Control.Monad.IO.Class (liftIO) 
import   Database.Persist 
import   Database.Persist.Sqlite 
import   Database.Persist.TH 
import   System.Environment 
import   Data.Text (Text,pack) 
import   Data.Time (UTCTime) 

share [mkPersist sqlSettings, mkMigrate "migrateAll"] [persistLowerCase| 
    Movie 
    title Text maxlen=20 
    year Int maxlen=11 
    genre Text Maybe maxlen=128 
    mpaa Text Maybe maxlen=16 
    director Text Maybe maxlen=128 
    actors Text Maybe maxlen=512 
    description Text Maybe maxlen=512 
    path Text Maybe maxlen=128 
    codec Text Maybe maxlen=32 
    length Int Maybe maxlen=11 
    poster Text Maybe maxlen=128 
    added UTCTime default=CURRENT_TIMESTAMP 
    Primary title year 
    deriving Show 
|] 

main :: IO() 
main = do 
    (path:args) <- getArgs 
    movies <- runSqlite (pack path) $ do 
    runMigration migrateAll 
    selectList [] [Desc MovieTitle] 

    mapM_ print movies 

這是一個人爲的例子,但它說明了我的觀點。我想要一個由titleyear組成的複合主鍵。所有東西都編譯好了,表格是用我需要的模式創建的。當我嘗試使用在我耶索德應用與persistent-sqlite上面定義的Movie類型,我得到了下面的編譯時錯誤

Foundation.hs:35:1: 
    No instance for (PathPiece MovieId) 
     arising from a use of ‘toPathPiece’ 
    In the first argument of ‘(:)’, namely ‘(toPathPiece dyn_apvA)’ 
    In the second argument of ‘(:)’, namely 
     ‘((toPathPiece dyn_apvA) : [])’ 
    In the expression: 
     ((Data.Text.pack "entry") : ((toPathPiece dyn_apvA) : [])) 

Foundation.hs:35:1: 
    No instance for (PathPiece MovieId) 
     arising from a use of ‘fromPathPiece’ 
    In the expression: fromPathPiece 
    In the pattern: fromPathPiece -> Just dyn_apwt 
    In the pattern: (:) (fromPathPiece -> Just dyn_apwt) [] 

我停留在這一點上,無法繼續我自己的。我嘗試過搜索,但是我只能找到不使用yesod的組合主鍵的工作示例。我有一種感覺,應該可以做到,因爲只使用persistent-sqlite這個複合主鍵。

這裏是Movie類型是如何在config/models

Movie 
    title Text maxlen=20 
    year Int maxlen=11 
    genre Text Maybe maxlen=128 
    mpaa Text Maybe maxlen=16 
    director Text Maybe maxlen=128 
    actors Text Maybe maxlen=512 
    description Text Maybe maxlen=512 
    path Text Maybe maxlen=128 
    codec Text Maybe maxlen=32 
    length Int Maybe maxlen=11 
    poster Text Maybe maxlen=128 
    added UTCTime default=CURRENT_TIMESTAMP 
    Primary title year 
    deriving 

回答

2

定義我還沒有實際使用的複合主鍵的功能自己,但這個錯誤對我來說很有意義。 Text對於任意組合鍵沒有明顯的序列化,因此持久化不會爲您生成。如果您想在網址中使用MovieId,則需要手動定義PathPiece實例,該實例只是一對用於轉換爲Text或從Text轉換而來的函數。