Haskell 持久 - 通过外键获取值
Haskell persistent - getting value via foreign key
假设我有一个非常简单的带有外键的数据库(为简化示例:一个 table 带有自引用;上下文 - 金融工具建模):
Instrument
ticker String
name String
denomination InstrumentId -- FK !!
domicile Country
source DataSource
UniqueT ticker
deriving Eq Show
然后我可以通过执行以下命令获取所有行:
getAll :: (MonadIO m, MonadLogger m) => SqlReadT m [Entity Instrument]
getAll = select $ from $ return
我注意到我可以使用自动生成的函数从结果中提取特定字段,例如
getTicker :: Entity Instrument -> String
getTicker = instrumentTicker . entityVal
但是,当我尝试引用通过外键引用的值时,我得到:
getDenomination :: Entity Instrument -> Key Instrument
getDenomination = instrumentDenomination . entityVal
我的问题:如何引用与收到的 "Key Instrument" 相对应的剩余值,例如如何获取引用记录的 "name" 字段?
编辑:
我已经尝试编写一个子查询,但目前还没有成功。我试过的是:
getInstrumentByKey :: (MonadIO m, MonadLogger m) => Key Instrument -> SqlBackendT m (Entity Instrument)
getInstrumentByKey key =
select $ from $ \i ->
where_ (i ^. InstrumentId ==. key) -- type error, InstrumentKey is of type "SqlExpr (Value (Key Instrument))", while key is "Key Instrument"
return i
如何在我的子查询中正确使用 "Key Instrument" 参数?
稍微扩展一下我 Al 在评论中所说的内容:
大体上,您有两种选择。一种是按 ID 进行另一次查找,如 Persistent documentation 中所述(请参阅 "fetching by ID" 部分)。这并不理想,因为它涉及到数据库的第二次访问。
但是由于您显然使用的是 SQL 数据库,这正是连接的用途。而且您已经在使用 Esqueleto,它允许您 "translate" SQL 查询 - 包括连接(您不能仅用 Persistent 表达) - 进入 Haskell。在这种情况下,您将使用 denomination
字段和 ID 将 table 加入自身。同样,图书馆的 documentation 很容易理解。
假设我有一个非常简单的带有外键的数据库(为简化示例:一个 table 带有自引用;上下文 - 金融工具建模):
Instrument
ticker String
name String
denomination InstrumentId -- FK !!
domicile Country
source DataSource
UniqueT ticker
deriving Eq Show
然后我可以通过执行以下命令获取所有行:
getAll :: (MonadIO m, MonadLogger m) => SqlReadT m [Entity Instrument]
getAll = select $ from $ return
我注意到我可以使用自动生成的函数从结果中提取特定字段,例如
getTicker :: Entity Instrument -> String
getTicker = instrumentTicker . entityVal
但是,当我尝试引用通过外键引用的值时,我得到:
getDenomination :: Entity Instrument -> Key Instrument
getDenomination = instrumentDenomination . entityVal
我的问题:如何引用与收到的 "Key Instrument" 相对应的剩余值,例如如何获取引用记录的 "name" 字段?
编辑:
我已经尝试编写一个子查询,但目前还没有成功。我试过的是:
getInstrumentByKey :: (MonadIO m, MonadLogger m) => Key Instrument -> SqlBackendT m (Entity Instrument)
getInstrumentByKey key =
select $ from $ \i ->
where_ (i ^. InstrumentId ==. key) -- type error, InstrumentKey is of type "SqlExpr (Value (Key Instrument))", while key is "Key Instrument"
return i
如何在我的子查询中正确使用 "Key Instrument" 参数?
稍微扩展一下我 Al 在评论中所说的内容:
大体上,您有两种选择。一种是按 ID 进行另一次查找,如 Persistent documentation 中所述(请参阅 "fetching by ID" 部分)。这并不理想,因为它涉及到数据库的第二次访问。
但是由于您显然使用的是 SQL 数据库,这正是连接的用途。而且您已经在使用 Esqueleto,它允许您 "translate" SQL 查询 - 包括连接(您不能仅用 Persistent 表达) - 进入 Haskell。在这种情况下,您将使用 denomination
字段和 ID 将 table 加入自身。同样,图书馆的 documentation 很容易理解。