Я довольно новичок в 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
Это своего рода надуманный пример, но он иллюстрирует мою мысль. Я хотел бы иметь составной первичный ключ, который состоит из title
и year
. Все компилируется отлично, и таблица создается с помощью схемы, которая мне нужна. Когда я пытаюсь использовать тип Movie
, как определено выше в моем Йесод применении с persistent-sqlite
, я получаю ошибку следующие во время компиляции
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