【发布时间】:2018-10-13 02:39:09
【问题描述】:
在我看到的所有示例中,esqueleto 的结果被投影到元组列表或entities records。
例如:
previousLogItems <- select $ from $ \li -> do
orderBy [desc (li ^. LogItemId)]
limit 10
return (li ^. LogItemId, li ^. LogItemTitle)
在 esqueleto 中是否有任何方法可以将列的子集投影到自定义记录(不同于实体)而不是元组?这是在没有从元组到自定义记录的额外投影的情况下完成的。
例如,假设从数据库中获取所有数据效率低下,因此我们只想将数据库中的 WindowTitle 和 BeginTime 列投影到具有适当名称的自定义记录中。
更新
无效代码示例:
data Custom = Custom
{ title :: Text
, id :: Int
} deriving (Eq, Show, Generic)
daily :: Servant.Handler [Custom]
daily = do
lis <- liftIO $ runDB $
select $ from $ \li -> do
orderBy [desc (li ^. LogItemId)]
limit 25
return (Custom (li ^. LogItemTitle) (li ^. LogItemId))
return lis
错误:
• Couldn't match expected type ‘Text’
with actual type ‘SqlExpr (Database.Esqueleto.Value Text)’
• In the first argument of ‘Custom’, namely ‘(li ^. LogItemTitle)’
In the first argument of ‘return’, namely
‘(Custom (li ^. LogItemTitle) (li ^. LogItemId))’
In a stmt of a 'do' block:
return (Custom (li ^. LogItemTitle) (li ^. LogItemId))
更新
无效代码示例:
daily :: Servant.Handler [Custom]
daily = do
lis <- liftIO $ runDB $
select $ from $ \li -> do
orderBy [desc (li ^. LogItemId)]
limit 25
return (Custom <$> (li ^. LogItemTitle) <*> (li ^. LogItemId))
return lis
错误:
• Couldn't match type ‘Database.Esqueleto.Value Text’ with ‘Text’
Expected type: SqlExpr Text
Actual type: SqlExpr (Database.Esqueleto.Value Text)
• In the second argument of ‘(<$>)’, namely ‘(li ^. LogItemTitle)’
In the first argument of ‘(<*>)’, namely
‘Custom <$> (li ^. LogItemTitle)’
In the first argument of ‘return’, namely
‘(Custom <$> (li ^. LogItemTitle) <*> (li ^. LogItemId))’
• Couldn't match type ‘Database.Esqueleto.Value (Key LogItem)’
with ‘Int’
Expected type: SqlExpr Int
Actual type: SqlExpr (Database.Esqueleto.Value (Key LogItem))
• In the second argument of ‘(<*>)’, namely ‘(li ^. LogItemId)’
In the first argument of ‘return’, namely
‘(Custom <$> (li ^. LogItemTitle) <*> (li ^. LogItemId))’
In a stmt of a 'do' block:
return (Custom <$> (li ^. LogItemTitle) <*> (li ^. LogItemId))
【问题讨论】:
-
我们不能在这里执行
fmap吗? -
我认为您可能必须实例化SqlSelect。我可能会看看元组实例的定义方式并从那里开始。
-
@WillemVanOnsem 我要求一种直接返回自定义记录的方法。没有去元组然后去自定义类型的低效率。
-
是的,但我在想
Custom <$> (li ^. LogItemTitle) <*> (li ^. LogItemId)。但现在我无法测试它:( -
@WillemVanOnsem 我认为提升它还不够。
select :: (SqlSelect a r, MonadIO m) => SqlQuery a -> SqlReadT m [r],据我所知,有一个从返回类型a到 SQL 表达式到最终类型r的实际转换。
标签: haskell tuples record esqueleto