从Python JSON迁移到Kotlin JVM JSON

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了从Python JSON迁移到Kotlin JVM JSON相关的知识,希望对你有一定的参考价值。

我有现有的Python程序使用import json并使用

json.load()  json.loads()

读取json并在易于使用的可访问字典中将其呈现在代码中的方法。

我使用python 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())

Contents of js document is this:

{
    "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
}

here is how Python can access above json document using [] and range

    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的目的。

答案

您可以使用Kotlins序列化框架中的Json.plain.parseJson(...)来获得类似的东西。它将创建一个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序列化插件包含在项目设置中。有关如何执行此操作,请参阅kotlinx.serialization Github项目。

由于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)
}

以上是关于从Python JSON迁移到Kotlin JVM JSON的主要内容,如果未能解决你的问题,请参考以下文章

从Java迁移到Kotlin,这14个App是怎么想的?

代码行数减少30-90%!多邻国从Java迁移到Kotlin的奇妙体验

从 LiveData 迁移到 Kotlin 数据流

Android 开发技术——从 LiveData 迁移到 Kotlin 数据流

Kotlin 无法导入 JSON 文件,即使使用显式路径

将JVM从JDK11迁移到JDK16的问题