How to create a table dynamically based on json data?
You need dynamic SQL for that, which carries the hazard of SQL injection.
However, done properly, this is safe against SQLi:

DO
$do$
BEGIN

EXECUTE (
   SELECT format('CREATE TABLE %I(%s)', metadata-&gt;&gt;'tablename', c.cols)
   FROM   public.json_metadata m
   CROSS  JOIN LATERAL (
      SELECT string_agg(quote_ident(col-&gt;&gt;'name')
                        || ' ' ||  (col-&gt;&gt;'datatype')::regtype, ', ') AS cols
      FROM   json_array_elements(metadata-&gt;'columns') col
      ) c
   );
END
$do$;


Table and column names are treated as case-sensitive. (You may want lower-case instead.) The type name is treated as case-insensitive, and any valid type name works.

Of course, this would raise an exception for the non-existent data type String you display. Try with text instead.

Note the use of format(), the object identifier type regclass, quote_ident(), the aggregation of columns in the LATERAL subquery and the DO command to execute dynamic SQL.

Related:


How to do this binary appearance analysis
SQL injection in Postgres functions vs prepared queries
Table name as a PostgreSQL function parameter