Parsing the JSON representation of database rows in Scala.js

二次信任 提交于 2019-12-24 16:24:21

问题


I am trying out scala.js, and would like to use simple extracted row data in json format from my Postgres database.

Here is an contrived example of the type of json I would like to parse into some strongly typed scala collection, features to note are that there are n rows, various column types including an array just to cover likely real life scenarios, don't worry about the SQL which creates an inline table to extract the JSON from, I've included it for completeness, its the parsing of the JSON in scala.js that is causing me problems

with inline_t as (  
select * from (values('One',1,True,ARRAY[1],1.0),
                     ('Six',6,False,ARRAY[1,2,3,6],2.4494),
                     ('Eight',8,False,ARRAY[1,2,4,8],2.8284)) as v (as_str,as_int,is_odd,factors,sroot))
select json_agg(t) from inline_t t;

 [{"as_str":"One","as_int":1,"is_odd":true,"factors":[1],"sroot":1.0}, 
 {"as_str":"Six","as_int":6,"is_odd":false,"factors":[1,2,3,6],"sroot":2.4494}, 
 {"as_str":"Eight","as_int":8,"is_odd":false,"factors":[1,2,4,8],"sroot":2.8284}]

I think this should be fairly easy using something like upickle or prickle as hinted at here: How to parse a json string to a case class in scaja.js and vice versa but I haven't been able to find a code example, and I'm not up to speed enough with Scala or Scala.js to work it out myself. I'd be very grateful if someone could post some working code to show how to achieve the above

EDIT This is the sort of thing I've tried, but I'm not getting very far

val jsparsed = scala.scalajs.js.JSON.parse(jsonStr3)

val jsp1 = jsparsed.selectDynamic("1")

val items = jsp1.map{ (item: js.Dynamic) =>
  (item.as_str, item.as_int, item.is_odd, item.factors, item.sroot)
  .asInstanceOf[js.Array[(String, Int, Boolean, Array[Int], Double)]].toSeq
}
println(items._1)

回答1:


So you are in a situation where you actually want to manipulate JSON values. Since you're not serializing/deserializing Scala values from end-to-end, serialization libraries like uPickle or Prickle will not be very helpful to you.

You could have a look at a cross-platform JSON manipulation library, such as circe. That would give you the advantage that you wouldn't have to "deal with JavaScript data structures" at all. Instead, the library would parse your JSON and expose it as a Scala data structure. This is probably the best option if you want your code to also cross-compile.

If you're only writing Scala.js code, and you want a more lightweight version (no dependency), I recommend declaring types for your JSON "schema", then use those types to perform the conversion in a safer way:

import scala.scalajs.js
import scala.scalajs.js.annotation._

// type of {"as_str":"Six","as_int":6,"is_odd":false,"factors":[1,2,3,6],"sroot":2.4494}
@ScalaJSDefined
trait Row extends js.Object {
  val as_str: String
  val as_int: Int
  val is_odd: Boolean
  val factors: js.Array[Int]
  val sroot: Double
}

type Rows = js.Array[Row]

val rows = js.JSON.parse(jsonStr3).asInstanceOf[Rows]

val items = (for (row <- rows) yield {
  import row._
  (as_str, as_int, is_odd, factors.toArray, sroot)
}).toSeq


来源:https://stackoverflow.com/questions/35363007/parsing-the-json-representation-of-database-rows-in-scala-js

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!