1

我正在使用 Scotty 和 PostgreSQL-simple 开发 Haskell API。我无法弄清楚如何插入包含文本数组的列。到目前为止,我的查询已经奏效,但是关于这个的一些问题似乎编译得不好。

这就是我所拥有的:

addOrder :: Postgres r m => OrderIntent -> m ()
addOrder param =
  void . withConn $ \conn -> execute conn qry (orderIntentTable param, orderIntentItemsSlug param)
  where
    qry = "insert into orders (table, items, created_at, updated_at) values (?, ?, now(), now())"

我的 OrderIntent 及其 FromRow 是:

data OrderIntent = OrderIntent
{ orderIntentTable :: Integer
, orderIntentItemsSlug :: [Text] 
} deriving(Eq, Show)

instance FromRow OrderIntent where
  fromRow = OrderIntent 
    <$> field
    <*> (fromPGArray <$> field)

我得到的错误是:

• Could not deduce (Database.PostgreSQL.Simple.ToField.ToField
                          [Data.Text.Internal.Text])
        arising from a use of ‘execute’
      from the context: Postgres r m
        bound by the type signature for:
                   addOrder :: forall r (m :: * -> *).
                               Postgres r m =>
                               OrderIntent -> m ()
        at Core/Order/DAO.hs:11:1-47

我不知道如何使用 PostgreSQL 库来解析文本数组,以便可以将我插入到数据库中。如果你们中的任何人可以帮助我,我将不胜感激!

PS:如果你碰巧知道 Scotty auth,我也有几天前的另一个拦截器。

4

2 回答 2

3

使用PGArray.

execute conn qry (orderIntentTable param, PGArray (orderIntentItemsSlug param))
于 2021-02-03T14:58:26.463 回答
0

当您插入orderIntentItemsSlugs 时,您需要一个(即 a )的ToField实例。这就是你的错误告诉你的。orderIntentItemsSlug[Text]

我建议查看其他ToField实例的来源,以弄清楚你想如何做到这一点(一个 hacky 方法是将你的字段变成第一个,它已经为实例Text加油)。ToField

您还可以编写一个订单表,一次orderID与一个项目相关联,然后您根本不必编写任何实例。

于 2021-02-03T14:46:25.397 回答