Our Community is getting an upgrade! To get everything ready for the relaunch, we’ll be placing the site in read-only mode starting September 21st.
We really appreciate your understanding while we get things set up behind the scenes. Catch up on all the exciting details about the move here.
Need help or have questions? Drop us a line at [email protected]
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.