如何将 BigQuery Struct Schema 字符串转换为 Javascript 对象?

Posted

技术标签:

【中文标题】如何将 BigQuery Struct Schema 字符串转换为 Javascript 对象?【英文标题】:How to convert BigQuery Struct Schema string to Javascript object? 【发布时间】:2019-08-12 06:08:04 【问题描述】:

我已从“INFORMATION_SCHEMA”表中提取了我的 BigQuery 表的架构。除了“结构”和“数组”数据类型之外,我以正确的 javascript 对象格式获取表中所有列的列表。我需要一种干净的方法将“Struct”和“Array”字符串转换为 javascript 对象。

我正在使用 NodeJS v11.2 我编写了一个小的正则表达式,它提取了以下内容。但是在得到输出之前拆分字符串并遍历每个单词似乎并不正确。我需要一种更简洁的方法来解决这个问题。

let structString = "STRUCT<name STRING, email STRING, time_sec INT64, tz_offset INT64, date STRUCT<seconds INT64, nanos INT64>>";

let _structSchema = structString.match(/STRUCT<([^)]+)>/)[1];

console.log(_structSchema); // name STRING, email STRING, time_sec INT64, tz_offset INT64, date STRUCT<seconds INT64, nanos INT64>

我需要编写一个递归函数,它会解析字符串并以下列方式给我输出。


  "name": "STRING",
  "email": "STRING",
  "time_sec": "INT64",
  "tz_offset": "INT64",
  "date": 
    "seconds": "INT64",
    "nanos": "INT64"
  

无论嵌套结构/数组的深度/层次如何,函数都应该运行。

【问题讨论】:

【参考方案1】:

使用正则表达式可以很好地标记输入字符串,但您需要更多逻辑来执行实际解析。

你可以这样做:

function parse(structString) 
    let tokenizer = /([a-z_]\w*)|\S|$/gi;
    
    function next(identifier, expected) 
        let match = tokenizer.exec(structString);
        function error(expected) 
            throw `Expected $expected but got $match[0] at $match.index`;
        
        match[0] = match[0] || "<EOF>";
        if (identifier && !match[1]) error(identifier);
        if (expected && !expected.includes(match[0])) error(expected.join(" or "))
        return match[0];
    
    
    function getType() 
        let fieldType = next("type identifier or STRUCT or ARRAY");
        if (fieldType === "STRUCT") 
            next(null, ["<"]);
            fieldType = ;
            do 
                fieldType[next("field identifier")] = getType();
             while (next(null, [",", ">"]) === ",");
         else if (fieldType === "ARRAY") 
            next(null, ["<"]);
            fieldType = [getType()];
            next(null, [">"]);
        
        return fieldType;
    
    
    let result = getType();
    next(null, ["<EOF>"]);
    return result;


// Sample input & call
let structString = "STRUCT<name STRING, email STRING, time_sec INT64, tz_offset INT64, date STRUCT<seconds INT64, nanos INT64>, phones ARRAY<STRING>>";
let obj = parse(structString);
console.log(obj);

【讨论】:

【参考方案2】:

如果您可以从您的环境中访问 Google Cloud Console,请考虑运行以下内容:bq show --format=pretty project:dataset.tablebq show --format=prettyjson project:dataset.table。您仍然需要为您的目的解析结果,但嵌套已经为您完成。

【讨论】:

以上是关于如何将 BigQuery Struct Schema 字符串转换为 Javascript 对象?的主要内容,如果未能解决你的问题,请参考以下文章

将 STRUCT 的 ARRAY 传递给标准 BigQuery SQL 的用户定义函数

BigQuery - 将通用 JSON 转换为 STRUCT

在 Bigquery 中,如何使用标准 Sql 过滤 Struct 数组以匹配 Struct 中的多个字段?

如何在 BigQuery 中将结构插入(或修改)到 ARRAY<STRUCT<STRING, STRUCT>>?

如何通过 BigQuery 中 STRUCT 类型的表达式解决分组问题

BigQuery:获取 STRUCT 的字段名称