使用 postgres-simple 在 FromRow 实例定义上出错
Error on a FromRow instance definition with postgres-simple
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 中的金额和总和字段指定什么。有人可以帮我吗?在使用 postgres-simple 库时,有没有更简单的方法来计算从 Haskell 类型到 SQL 类型的类型转换,反之亦然?
Double
有一个 FromField
实例,但它不适用于 numeric
,因为 numeric
是可变精度 as per the PostgresSQL documentation. If you look at the postgresql-simple
documentation 你会看到 Ratio Integer
(又名 Rational
)实例 确实 支持 numeric
。
所以您在这里可以做的是以下两件事之一:
- 为您的
amount
字段使用 Rational
而不是 Double
- 确定你可以接受失去精度(尽管你为什么在 SQL 端使用
numeric
?),然后做一些类似 的事情
import Data.Ratio
loseNumericPrecision :: Postgres.RowParser Double
loseNumericPrecision = fmap fromRational Postgres.field
并使用它代替 Postgres.field
对应于 numeric
值的字段。
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 中的金额和总和字段指定什么。有人可以帮我吗?在使用 postgres-simple 库时,有没有更简单的方法来计算从 Haskell 类型到 SQL 类型的类型转换,反之亦然?
Double
有一个 FromField
实例,但它不适用于 numeric
,因为 numeric
是可变精度 as per the PostgresSQL documentation. If you look at the postgresql-simple
documentation 你会看到 Ratio Integer
(又名 Rational
)实例 确实 支持 numeric
。
所以您在这里可以做的是以下两件事之一:
- 为您的
amount
字段使用Rational
而不是Double
- 确定你可以接受失去精度(尽管你为什么在 SQL 端使用
numeric
?),然后做一些类似 的事情
import Data.Ratio
loseNumericPrecision :: Postgres.RowParser Double
loseNumericPrecision = fmap fromRational Postgres.field
并使用它代替 Postgres.field
对应于 numeric
值的字段。