Переход с Python JSON на Kotlin JVM JSON
У меня есть существующие программы на Python, которые используют import json
и использовать
json.load() json.loads()
способ прочитать JSON и представить его в коде в простом в использовании доступном словаре.
Я использую питон json[name][] = value
создает ссылки на данные json в памяти, а также использует синтаксис того же типа для назначения новых значений элементам json.
Я хочу перенести код Python в Kotlin и искать библиотеки JSON, которые будут делать что-то похожее на то, что Python json.load () делает в Kotlin.
Я использовал Google, но ничего не нашел, есть много библиотек Kotlin / Java JSON, но я не думаю, что они предлагают что-то вроде методов загрузки Python JSON.
Какую библиотеку лучше всего использовать?
Вот детали кода Python, я хочу сделать то же самое в Kotlin и использовать существующие библиотеки JSON.
import json
js = json.loads(response['Body'].read())
Содержание документа JS это:
{
"environment": "production",
"postgres_host" : "pgstaging-prod.blah.blah.rds.amazonaws.com",
"postgres_port" : 5432,
"postgres_database" : "datawarehouse",
"postgres_user" : "pguser",
"postgres_password" : "!!!!!!",
"postgres_config_schema" : "etl_operations",
"postgres_validation_log_table_name" : "jobs_process_log",
"postgres_destination_table_name" : "myleads",
"debugFlag": true,
"configBucket": "csn-datalake",
"configFileName": "yurib_test/myleads.json",
"HighWaterMarkFileName": "yurib_test/dts_high_watermark.json",
"repartitionSourceTableName": "leads",
"repartitionSourceDbName": "datalake",
"sourceTablePartitionDateTime": "job_run_timestamp_utc",
"repartitionTargetTableName": "outleads",
"repartitionTargetDbName": "datalake_reports",
"repartitionTargetS3Location": "yurib_test/outleads",
"repartitionTargetColumnList": [
{"colName": "message_item_countrycode", "isDatePartition": false, "renameTo" : "message_countrycode"},
{"colName": "message_tenant_code", "isDatePartition": false, "renameTo" : "message_tenant"},
{"colName": "message_lastupdated", "isDatePartition": true, "renameTo" : "message_lastupdated"}
],
"repartitionLoadType": "incremental_data_load",
"repartition": 4,
"repartitionLoadTypeIncremental": "incremental_data_load",
"repartitionLoadTypeFullInitial": "full_data_load",
"countryCodeColName": "message_item_countrycode",
"tenantColName": "message_tenant_code",
"autoCreateCountryTenant": false,
"autoCreateCountry": true,
"autoCreateTenant": true,
"partitionDateDefault": "0000-00-00",
"partitionYearDefault": "0000",
"partitionMonthDefault": "00",
"partitionDayDefault": "00",
"countryCodeDefault": "AU",
"tenantDefault": "CARSALES",
"missingPartColDataValReplace": "MISSINGDATA",
"validateIncomingCountryTenant": true,
"datePartitionStyle": "ym",
"datePartitionStyleYearMonth": "ym",
"datePartitionStyleYearMonthDay": "ymd",
"propagateGlueJobRunGuid": false
}
вот как Python может получить доступ к документу выше json, используя [] и диапазон
print (js["repartitionLoadType"])
print (js['configBucket'], js['configFileName'], js['HighWaterMarkFileName'])
print (js['repartitionTargetTableName'], js['repartitionTargetS3Location'])
print (js['repartitionSourceTableName'], js['repartitionSourceDbName'])
print (js['repartitionTargetDbName'], js['repartitionLoadType'])
print (js['autoCreateCountry'], js['autoCreateTenant'], js['missingPartColDataValReplace'])
print (js['countryCodeColName'], js['tenantColName'], js['propagateGlueJobRunGuid'])
print (js['countryCodeDefault'], js['tenantDefault'], js['validateIncomingCountryTenant'], js['repartition'])
partition_dts = ""
# json array
for i in range(0, len(js['repartitionTargetColumnList'])):
if True == js['repartitionTargetColumnList'][i]['isDatePartition']:
partition_dts = "`" + js['repartitionTargetColumnList'][i]['colName'] + "`"
else:
js['repartitionTargetColumnList'][i]['colName'] = "new value replace/assign here"
continue
# to set/replace/assign any values above:
js["repartitionLoadType"] = "some new value"
Я надеюсь, что это проясняет, что я пытаюсь сделать, чтобы перенести мой код Python в Kotlin.
1 ответ
Ты можешь использовать Json.plain.parseJson(...)
из среды сериализации Kotlins, чтобы получить что-то подобное. Он создаст дерево объектов Json, по которым можно перемещаться как карта карт.
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.content
import java.lang.StringBuilder
fun main() {
val js = Json.plain.parseJson(data).jsonObject
println(js["repartitionLoadType"]?.content)
// ...
var partitionDts = StringBuilder()
for (repartitionTargetColumn in js["repartitionTargetColumnList"]!!.jsonArray) {
if (repartitionTargetColumn.jsonObject["isDatePartition"]?.primitive?.boolean!!) {
partitionDts.append("`" + repartitionTargetColumn.jsonObject["colName"] + "`");
}
else {
// JsonObjects are immutable in Kotlin
// repartitionTargetColumn.jsonObject["colName"] = "new value replace/assign here"
}
}
}
Обязательно включите плагин сериализации Kotlin в настройку вашего проекта. Посмотрите, как это сделать, на GitHub- проекте https://github.com/Kotlin/kotlinx.serialization.
Поскольку Kotlin является языком статической типизации, вам, вероятно, следует определить класс данных для вашего Json-файла и проанализировать этот файл в объект этого класса данных, а не использовать вышеописанный нетипизированный подход.
import kotlinx.serialization.Serializable
import kotlinx.serialization.json.Json
@Serializable
data class BodyData(
var environment: String,
var repartitionLoadType: String
// ...
)
fun main() {
val bodyData = Json.nonstrict.parse(BodyData.serializer(), data)
println(bodyData.repartitionLoadType)
}