Created on 12-14-2017 09:57 PM - edited 09-16-2022 01:41 AM
I needed to build a quick SQL table from a JSON. There's some online tools, but I'd rather Java this process.
It works okay enough, now I am wondering if this would make a good Apache NiFi processor
package com.dataflowdeveloper.processors.process;
import java.util.Iterator;
import java.util.Map;
import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
public class JsonToDDL {
/**
*
* @param tableName
* @param json
* @return String DDL SQL
*/
public String parse(String tableName, String json) {
JsonFactory factory = new JsonFactory();
StringBuilder sql = new StringBuilder(256);
sql.append("CREATE TABLE ").append(tableName).append(" ( ");
ObjectMapper mapper = new ObjectMapper(factory);
JsonNode rootNode = null;
try {
rootNode = mapper.readTree(json);
} catch (Exception e) {
e.printStackTrace();
}
Iterator<Map.Entry<String, JsonNode>> fieldsIterator = rootNode.fields();
while (fieldsIterator.hasNext()) {
Map.Entry<String, JsonNode> field = fieldsIterator.next();
System.out.println("Key: " + field.getKey() + "\tValue:" + field.getValue());
sql.append(field.getKey());
if (field.getValue().canConvertToInt()) {
sql.append(" INT, ");
} else if (field.getValue().canConvertToLong()) {
sql.append(" LONG, ");
} else if (field.getValue().asText().contains("/")) {
sql.append(" DATE, ");
} else if (field.getValue().asText().contains("-")) {
sql.append(" DATE, ");
} else if (field.getValue().asText().length() > 25) {
sql.append(" VARCHAR( ").append( field.getValue().asText().length() + 25 ) .append("), ");
} else {
sql.append(" VARCHAR(25), ");
}
}
// end table
sql.deleteCharAt(sql.length() - 2);
sql.append(" ) ");
return sql.toString();
}
public static void main(String[] args) {
JsonToDDL ddl = new JsonToDDL();
String json = "{\"EMP_ID\":3001,\"DURATION_SEC\":288000,\"LOG_DATE\":\"2017-11-07 10:00:00\"}";
String ddlSQL = ddl.parse("TIME_LOG", json);
System.out.println("DDL=" + ddlSQL);
json = " {\"EMP_ID\":4001,\"GENDER\": \"M\",\"DEPT_ID\":4, \"FIRST_NAME\":\"Brett\",\"LAST_NAME\" :\"Lee\"}";
ddlSQL = ddl.parse("EMPLOYEE", json);
System.out.println("DDL=" + ddlSQL);
json = "{\"DEPT_ID\":1,\"CODE\": \"FN\",\"NAME\":\"Finance\",\"DESCRIPTION\" :\"Finance Department\",\"ACTIVE\":1}";
ddlSQL = ddl.parse("DEPARTMENT", json);
System.out.println("DDL=" + ddlSQL);
}
}
In tests it looks okay. I do some guessing of what type something should be from the JSON value.
I was also thinking I could hook this up to Avro Tools to do some other type investigation.
So should I make this a processor? Or just a little script.
Reference:
Created on 02-12-2018 04:52 PM
Perhaps we could add "CREATE TABLE" and other DDL commands to ConvertJsonToSQL? The hardest part of the exercise is to infer the types correctly, it's such a difficult problem that there's often a "why bother?" attitude, or the type inference is "good enough" for 80% of the use cases, etc.
Created on 01-16-2019 03:14 PM
How to do it in reverse way, like ddl to json?
Created on 03-30-2020 02:49 PM
Hmmm DDL to JSON is not a bad idea.