Haskell постоянный - получение значения через внешний ключ - PullRequest
0 голосов
/ 30 марта 2020

Давайте предположим, что у меня есть очень простая БД с внешним ключом (для простоты примера: одна таблица с собственной ссылкой; контекст - моделирование финансового инструмента):

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

Я заметил, что я могу извлечь определенные c поля из результатов, используя автоматически сгенерированные функции, например,

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

Однако, когда я пытаюсь обратиться к значению, указанному через внешний ключ, я получаю:

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

Мой вопрос: как я могу сослаться на оставшиеся значения, которые соответствуют полученному «Ключевому инструменту», например, как я могу получить «имя» поле указанной записи?

РЕДАКТИРОВАТЬ:

Я пытался написать подзапрос, но пока ничего хорошего. Я попробовал:

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

Как правильно использовать аргумент «Ключевой инструмент» в моем подзапросе?

1 Ответ

1 голос
/ 01 апреля 2020

Немного поясняя сказанное в комментариях Ала:

В общем, у вас есть два варианта для этого. Один из них - выполнить другой поиск по идентификатору, как описано в Постоянная документация (см. Раздел «Выборка по идентификатору»). Это не идеально, потому что это включает в себя вторую поездку в базу данных.

Но поскольку вы явно используете базу данных SQL, это именно то, для чего нужны объединения. И вы уже используете Esqueleto, который позволяет вам «переводить» SQL запросов - включая объединения (которые вы не можете express только с постоянными) - в Haskell. В этом случае вы присоединитесь к своей таблице, используя поле denomination и идентификатор. Снова, библиотека документация проста для отслеживания.

...