我正在尝试将 Persistent 与 Servant 一起使用,因此我无法将 URL 段自动解析为 Persistent 键。相反,我已将路由设置为需要Int64
,并且我想使用它来检索记录以执行主键查找。
我发现的所有内容都 指向用于toSqlKey
将整数转换为键,因此我尝试编写一个非常简单的函数来为我做到这一点:
runDB :: (MonadBaseControl IO m, MonadIO m) => (SqlPersistT (NoLoggingT (ResourceT m))) a -> m a
runDB actions = do
filename <- liftIO $ getEnv "SQLITE_FILENAME"
runSqlite (pack filename) actions
getRecordByKey :: Int64 -> IO (Maybe (Entity Record))
getRecordByKey recordId = runDB $ get (toSqlKey recordId)
不幸的是,这不起作用。我收到以下类型错误:
Couldn't match expected type ‘PersistEntityBackend
(Entity Record)’
with actual type ‘SqlBackend’
In the second argument of ‘($)’, namely ‘get (toSqlKey recordId)’
In the expression: runDB $ get (toSqlKey recordId)
In an equation for ‘getRecordByKey’:
getRecordByKey recordId = runDB $ get (toSqlKey recordId)
我有点理解这个错误——我查找了get
and的类型toSqlKey
,它们包括相关的约束:
get :: (MonadIO m, backend ~ PersistEntityBackend val, PersistEntity val) => Key val -> ReaderT backend m (Maybe val)
toSqlKey :: ToBackendKey SqlBackend record => Int64 -> Key record
如果我理解正确,backend
并且PersistEntityBackend val
需要是相同的类型,但toSqlKey
强制执行SqlBackend
约束,那么类型不匹配。我的直觉告诉我PersistentEntityBackend (Entity Record)
应该是 SqlBackend
,但显然我错了。不过,我不知道为什么或如何。
无论如何,我不知道我在该分析中是对还是错,但无论哪种方式,我都不确定如何解决这个问题或这样做的正确方法是什么。给定一个整数,我如何/应该从我的数据库中获取记录?