在scala框架中支持PostgreSQL特定的array_agg函数?

时间:2015-01-19 06:27:17

标签: postgresql scala slick anorm squeryl

是否有一些scala关系数据库框架(anorm,squeryl等等)使用类似postgres的聚合器在分组后生成列表,或者至少模拟其使用?

我希望实现两个级别:

  • “标准”文件,其中至少任何带有array_agg的SQL分组都会转换为正在聚合的类型的列表,

  • 和“scala ORM powered”允许某种类型的连接,以便如果聚合是其他表的外键,则生成另一个表的元素列表。当然,最后这件事超出了SQL的范围,但如果我使用的是更强大的语言,我不介意使用类固醇。

我发现特别有趣的是,光滑的文档(正是基于允许使用scala group-by表示法),似乎明确否定了列表的输出结果。

编辑:用例

您拥有典型的多对多表,例如产品和供应商,对(p_id,s_id)。您想要为每种产品生成供应商列表。所以postgresql查询应该是

SELECT p_id, array_agg(s_id) from t1 group by p_id

人们可以期待一些惯用的方式,但我不知道如何。此外,如果我们去一些ORM,那么我们也可以分别在p_id和s_id上考虑与表产品和供应商的连接,并获得包含对象的zip(产品,(supplier1,supplier2,supplierN))的答案。不仅是ids

3 个答案:

答案 0 :(得分:2)

我也不确定我是否理解你的问题是否正确,你能详细说明一下吗?

在光滑方面,您目前无法使用postgres“array_agg”或“string_agg”作为Query类型的方法。如果要使用此特定功能,则需要使用自定义sql。但是:我前段时间添加了一个问题(https://github.com/slick/slick/issues/923,你应该按照这个讨论进行讨论),我们有一个来自cvogt的原型准备就绪。

我过去需要使用“string_agg”并为其添加补丁(请参阅https://github.com/mobiworx/slick/commit/486c39a7ed90c9ccac356dfdb0e5dc5c24e32d63),所以这可能对您有所帮助。请查看“AggregateTest”以了解有关它的更多信息。

另一种可能性是将“array_agg”的用法封装在数据库视图中,并将此视图与光滑使用。这样您就不需要直接在光滑中使用“array_agg”了。

答案 1 :(得分:1)

您可以使用slick-pg

supports array_agg和其他聚合函数。

答案 2 :(得分:0)

你的问题很有趣,关心它如何理想地看起来如何?当你group by时,你经常会有一个额外的列,例如count(*)超出你的case类的标准列,那么你的List的类型是什么?

我的大多数(anorm)方法要么返回单例(可能是Option),要么返回该类的类型。对于每个案例类,我都有一个sqlFields变量(例如m.id, m.name, m.forManufacturer)和一个我引用为.as(modelParser.singleOpt).as(modelParser *)的解析器变量。对于外键,案例类级别的lazy val(如果需要,则为def)非常有用。例如。如果我有模型和制造商实体,模型上有外键forManufacturer,那么我可以在模型的案例类中定义lazy val manufacturer : Manufacturer = ...,这样我可以随时引用{{1 }}。我可以用这种方式将连接定义为自己的方法,或者作为伴随对象中的方法。

不是100%肯定我正在回答你的问题,但认为这有点长的评论。

编辑:如果您的驱动程序支持解析postgresql数组,您可以将它们直接映射到model.manufacturer(甚至ProductSuppliers(id:Int, suppliers:List[Int])这样的类?)在一个类似于一个惯用语的anorm中可以得到,我想?对于不支持它的数据库,在我看来类似于List[Supplier]版本,即order by,您可以select p1, s1 from t1 order by p1并类似地映射到ProductSuppliers。