有没有一种编程方式可以将JSON转换为AVRO模式?

11

我需要创建 AVRO 文件,但为此我需要两个东西:

1)JSON

2)Avro 模式

从这两个要求中 - 我已经有了 JSON:

{"web-app": {
  "servlet": [   
    {
      "servlet-name": "cofaxCDS",
      "servlet-class": "org.cofax.cds.CDSServlet",
      "init-param": {
        "configGlossary:installationAt": "Philadelphia, PA",
        "configGlossary:adminEmail": "ksm@pobox.com",
        "configGlossary:poweredBy": "Cofax",
        "configGlossary:poweredByIcon": "/images/cofax.gif",
        "configGlossary:staticPath": "/content/static",
        "templateProcessorClass": "org.cofax.WysiwygTemplate",
        "templateLoaderClass": "org.cofax.FilesTemplateLoader",
        "templatePath": "templates",
        "templateOverridePath": "",
        "defaultListTemplate": "listTemplate.htm",
        "defaultFileTemplate": "articleTemplate.htm",
        "useJSP": false,
        "jspListTemplate": "listTemplate.jsp",
        "jspFileTemplate": "articleTemplate.jsp",
        "cachePackageTagsTrack": 200,
        "cachePackageTagsStore": 200,
        "cachePackageTagsRefresh": 60,
        "cacheTemplatesTrack": 100,
        "cacheTemplatesStore": 50,
        "cacheTemplatesRefresh": 15,
        "cachePagesTrack": 200,
        "cachePagesStore": 100,
        "cachePagesRefresh": 10,
        "cachePagesDirtyRead": 10,
        "searchEngineListTemplate": "forSearchEnginesList.htm",
        "searchEngineFileTemplate": "forSearchEngines.htm",
        "searchEngineRobotsDb": "WEB-INF/robots.db",
        "useDataStore": true,
        "dataStoreClass": "org.cofax.SqlDataStore",
        "redirectionClass": "org.cofax.SqlRedirection",
        "dataStoreName": "cofax",
        "dataStoreDriver": "com.microsoft.jdbc.sqlserver.SQLServerDriver",
        "dataStoreUrl": "jdbc:microsoft:sqlserver://LOCALHOST:1433;DatabaseName=goon",
        "dataStoreUser": "sa",
        "dataStorePassword": "dataStoreTestQuery",
        "dataStoreTestQuery": "SET NOCOUNT ON;select test='test';",
        "dataStoreLogFile": "/usr/local/tomcat/logs/datastore.log",
        "dataStoreInitConns": 10,
        "dataStoreMaxConns": 100,
        "dataStoreConnUsageLimit": 100,
        "dataStoreLogLevel": "debug",
        "maxUrlLength": 500}},
    {
      "servlet-name": "cofaxEmail",
      "servlet-class": "org.cofax.cds.EmailServlet",
      "init-param": {
      "mailHost": "mail1",
      "mailHostOverride": "mail2"}},
    {
      "servlet-name": "cofaxAdmin",
      "servlet-class": "org.cofax.cds.AdminServlet"},

    {
      "servlet-name": "fileServlet",
      "servlet-class": "org.cofax.cds.FileServlet"},
    {
      "servlet-name": "cofaxTools",
      "servlet-class": "org.cofax.cms.CofaxToolsServlet",
      "init-param": {
        "templatePath": "toolstemplates/",
        "log": 1,
        "logLocation": "/usr/local/tomcat/logs/CofaxTools.log",
        "logMaxSize": "",
        "dataLog": 1,
        "dataLogLocation": "/usr/local/tomcat/logs/dataLog.log",
        "dataLogMaxSize": "",
        "removePageCache": "/content/admin/remove?cache=pages&id=",
        "removeTemplateCache": "/content/admin/remove?cache=templates&id=",
        "fileTransferFolder": "/usr/local/tomcat/webapps/content/fileTransferFolder",
        "lookInContext": 1,
        "adminGroupID": 4,
        "betaServer": true}}],
  "servlet-mapping": {
    "cofaxCDS": "/",
    "cofaxEmail": "/cofaxutil/aemail/*",
    "cofaxAdmin": "/admin/*",
    "fileServlet": "/static/*",
    "cofaxTools": "/tools/*"},

  "taglib": {
    "taglib-uri": "cofax.tld",
    "taglib-location": "/WEB-INF/tlds/cofax.tld"}}}

但如何基于它创建AVRO Schema?

寻找编程方式来做这件事情,因为会有多个Schema,每次都手动创建Avro Schema是不现实的。

我尝试过'avro-tools-1.8.1.jar',但它无法直接从JSON创建Avro Schema。

寻找能够创建JSON -> Avro schema的Jar包或Python代码。如果数据类型不完美(字符串、整数和浮点数对于初始阶段已经足够),也没关系。


JSON基本上是无模式的。这个JSON的来源是什么? - Elliott Frisch
谢谢。我知道JSON是无模式的。但是,在我的项目中,不同的客户有不同的JSON格式,并将其发送给我。将会有许多不同的JSON格式 - 上面只是一个例子。我没有能力强制他们创建AVRO格式,但是我的项目需要AVRO格式。我有两个选择:1)手动为每个客户创建每个JSON的AVRO模式,2)尝试使用一些代码来自动创建基于JSON的AVRO模式(即使不完美)。正在寻找第二个选项。谢谢。 - Joe
Store it as a String. - Elliott Frisch
我无法使用 String。项目需要 AVRO 格式,不接受 String。 - Joe
4个回答

12

这个对我救命了!太棒了。 - Susheel Javadi
这可以工作。然而,如果你的JSON在键字段中有空格,它将包含在Avro名称中,这是无效的。你需要把空格去掉。添加下划线或其他字符。否则看起来似乎可以工作。如果没有其他问题,这是了解复杂结构如何在Avro中格式化的好方法。 - ajpieri
@ajpieri该工具现在可以处理JSON属性名称中的空格,通过将其替换为另一个字符,如下划线。 - Partho
1
这不再是一个免费服务。 - vlyalcin

12

您可以使用Kite SDK工具从JSON输入推断出Avro模式。

https://github.com/kite-sdk/kite/blob/master/kite-data/kite-data-core/src/main/java/org/kitesdk/data/spi/JsonUtil.java#L539

示例:

    String json = "{\n" +
            "    \"id\": 1,\n" +
            "    \"name\": \"A green door\",\n" +
            "    \"price\": 12.50,\n" +
            "    \"tags\": [\"home\", \"green\"]\n" +
            "}\n"
            ;
    String avroSchema = JsonUtil.inferSchema(JsonUtil.parse(json), "myschema").toString();
    System.out.println(avroSchema);

结果:

{  
   "type":"record",
   "name":"myschema",
   "fields":[  
      {  
         "name":"id",
         "type":"int",
         "doc":"Type inferred from '1'"
      },
      {  
         "name":"name",
         "type":"string",
         "doc":"Type inferred from '\"A green door\"'"
      },
      {  
         "name":"price",
         "type":"double",
         "doc":"Type inferred from '12.5'"
      },
      {  
         "name":"tags",
         "type":{  
            "type":"array",
            "items":"string"
         },
         "doc":"Type inferred from '[\"home\",\"green\"]'"
      }
   ]
}

您可以在这里找到maven依赖。


6

试一下这个链接:http://www.dataedu.ca/avro

它可以基本推断出接受JSON的Avro schema。

你甚至可以给它一个JSON数组。它会生成一个与你数组中所有的JSON文档兼容的Avro schema。

还有其他工具可以验证结果。


0
如果您想避免为每个JSON格式创建专用的AVRO模式,可以使用rec-avro包。
它允许您获取任何Python数据结构,包括解析的XML或JSON,并将其存储在Avro中,而无需专用模式。
我已经测试了Python 3。
您可以通过pip3 install rec-avro安装它,或者查看https://github.com/bmizhen/rec-avro上的代码和文档。
我在这里提供了一个JSON到AVRO的示例代码:https://dev59.com/7X3aa4cB1Zd3GeqPe5Ce#55444481

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接