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。 cumulativeRevenue提供如下例外。你可以忽略spock部分。
Spock Error while handling ["cumulative"]: Incompatible {errSQLType = "numeric", errSQLTableOid = Nothing, errSQLField = "amount", errHaskellType = "Double", errMessage = "types incompatible"}
我不清楚在CumulativeRevenue中为amount和sum字段指定什么。有人可以帮助我吗?在使用postgres-simple库时,有没有更简单的方法来计算从Haskell类型到SQL类型的转换类型,反之亦然?
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
值。