data CumulativeRevenue = CumulativeRevenue
{ payment_date :: T.Text
, amount :: Double
, sum :: Double
} deriving (Show, Generic, Aeson.ToJSON, Aeson.FromJSON)
instance Postgres.FromRow CumulativeRevenue where
fromRow = CumulativeRevenue
<$> Postgres.field
<*> Postgres.field
<*> Postgres.field
cumulativeRevenue :: Postgres.Connection -> IO [CumulativeRevenue]
cumulativeRevenue conn = Postgres.query_ conn
"SELECT payment_date, amount, sum(amount) OVER (ORDER by payment_date) \
\ FROM (\
\ SELECT CAST (payment_date as TEXT) AS payment_date, SUM(amount) AS \
\ amount \
\ FROM payment \
\ GROUP BY CAST(payment_date AS TEXT) \
\ ) p \
\ ORDER BY payment_date \
\"
目前,我有上面的代码。完整的代码是here。累积收入给出了以下异常。您可以忽略spock部分。
Spock Error while handling ["cumulative"]: Incompatible {errSQLType = "numeric", errSQLTableOid = Nothing, errSQLField = "amount", errHaskellType = "Double", errMessage = "types incompatible"}
我不清楚在CumulativeRevenue中为数量和总和字段指定什么。有人可以帮我吗?使用postgres-simple库时,有没有更简单的方法来找出从Haskell类型到SQL类型的类型转换,反之亦然?
答案 0 :(得分:0)
FromField
有一个Double
实例,但是它不适用于numeric
,因为numeric
是精度为as per the PostgresSQL documentation的变量。如果查看postgresql-simple
documentation,您会发现Ratio Integer
(又名Rational
)实例确实支持numeric
。
所以您可以在这里做两件事之一:
Rational
字段中使用Double
代替amount
numeric
?),然后做类似的事情import Data.Ratio
loseNumericPrecision :: Postgres.RowParser Double
loseNumericPrecision = fmap fromRational Postgres.field
,并将其代替Postgres.field
用于与numeric
值相对应的字段。