简体   繁体   English

Haskell 持久化 - 通过外键获取价值

[英]Haskell persistent - getting value via foreign key

Let's assume I've got a very simple db with a Foreign Key (for simplicity of the example: one table with a self reference; context - modelling a financial instrument):让我们假设我有一个非常简单的带有外键的数据库(为了简单起见:一个带有自我引用的表;上下文 - 对金融工具建模):

Instrument
    ticker String
    name String
    denomination InstrumentId -- FK !!
    domicile Country
    source DataSource
    UniqueT ticker
    deriving Eq Show

I can then get all rows by executing:然后我可以通过执行来获取所有行:

getAll :: (MonadIO m, MonadLogger m) => SqlReadT m [Entity Instrument]
getAll = select $ from $ return

I noticed that I can extract specific fields from the results using autogenerated functions, eg我注意到我可以使用自动生成的函数从结果中提取特定字段,例如

getTicker :: Entity Instrument -> String
getTicker = instrumentTicker . entityVal

However, when I try referring to the value referenced via the foreign key, I get:但是,当我尝试引用通过外键引用的值时,我得到:

getDenomination :: Entity Instrument -> Key Instrument
getDenomination = instrumentDenomination . entityVal

My question: how can I refer to the remaining values that correspond to the "Key Instrument" received, eg how can I get "name" field of the referenced record ?我的问题:我如何引用与接收到的“Key Instrument”相对应的剩余值,例如如何获取引用记录的“name”字段?

EDIT:编辑:

I've tried writing a subquery, but no good so far.我试过写一个子查询,但到目前为止还不好。 What I tried was:我尝试的是:

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

How can I use the "Key Instrument" arg properly in my subquery ?如何在我的子查询中正确使用“Key Instrument”参数?

Expanding just a little on what I've Al said in the comments:稍微扩展一下我在评论中所说的话:

Broadly, you have two options for this.总的来说,您有两种选择。 One is to do another lookup by ID, as explained in the Persistent documentation (see the section "fetching by ID").一种是按 ID 进行另一次查找,如Persistent 文档中所述(请参阅“按 ID 获取”部分)。 This is not ideal, because it involves a second trip to the database.这并不理想,因为它涉及对数据库的第二次访问。

But since you are clearly using an SQL database, this is exactly what joins are for.但由于您显然使用的是 SQL 数据库,这正是连接的用途。 And you're already using Esqueleto, which allows you to "translate" SQL queries - including joins (which you can't express with just Persistent) - into Haskell.而且您已经在使用 Esqueleto,它允许您将 SQL 查询 - 包括连接(您无法仅用 Persistent 表达) - 转换为 Haskell。 In this case you'd be joining your table onto itself, using the denomination field and the ID.在这种情况下,您将使用denomination字段和 ID 将您的表连接到其自身上。 Again, the library's documentation is easy to follow.同样,图书馆的文档很容易理解。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM