Livy Server: вернуть фрейм данных как JSON?

Я выполняю инструкцию на сервере Livy, используя HTTP POST call to localhost:8998/sessions/0/statements, со следующим телом

{
  "code": "spark.sql("select * from test_table limit 10")"
}

Я хотел бы получить ответ в следующем формате

(...)
"data": {
  "application/json": "[
    {"id": "123", "init_date": 1481649345, ...},
    {"id": "133", "init_date": 1481649333, ...},
    {"id": "155", "init_date": 1481642153, ...},
  ]"
}
(...)

но я вижу

(...)
"data": {
  "text/plain": "res0: org.apache.spark.sql.DataFrame = [id: string, init_date: timestamp ... 64 more fields]"
}
(...)

что это toString() версия фрейма данных.

есть ли способ вернуть фрейм данных как JSON с помощью сервера Livy?

редактировать

найдена проблема JIRA, которая решает проблему: https://issues.cloudera.org/browse/LIVY-72

по комментариям можно сказать, что Livy не поддерживает и не будет поддерживать такую функцию?

3 ответов


У меня нет большого опыта работы с Livy, но, насколько я знаю, эта конечная точка используется в качестве интерактивной оболочки, и вывод будет строкой с фактическим результатом, который будет показан оболочкой. Поэтому, имея это в виду, я могу придумать способ подражать результату, который вы хотите, но это может быть не лучший способ сделать это:

{
  "code": "println(spark.sql(\"select * from test_table limit 10\").toJSON.collect.mkString(\"[\", \",\", \"]\"))"
}

тогда у вас будет JSON, завернутый в строку, чтобы ваш клиент мог ее разобрать.


Я рекомендую использовать встроенный (хотя и трудно найти документацию) магия %json и %table:

%json

session_url = host + "/sessions/1"
statements_url = session_url + '/statements'
data = {
        'code': textwrap.dedent("""\
        val d = spark.sql("SELECT COUNT(DISTINCT food_item) FROM food_item_tbl")
        val e = d.collect
        %json e
        """)}
r = requests.post(statements_url, data=json.dumps(data), headers=headers)
print r.json()

%table

session_url = host + "/sessions/21"
statements_url = session_url + '/statements'
data = {
        'code': textwrap.dedent("""\
        val x = List((1, "a", 0.12), (3, "b", 0.63))
        %table x
        """)}
r = requests.post(statements_url, data=json.dumps(data), headers=headers)
print r.json()

по теме: Apache Livy: запрос Spark SQL через REST: возможно?


Я думаю, что в целом ваш лучший выбор-записать свой вывод в какую-то базу данных. Если вы пишете в таблицу со случайным именем, вы можете прочитать свой код после завершения сценария.