Display records of any tables from Database

Hello, I am connecting to a postgresql database through Node-red dashboard
I would like to do a dashboard that allow me to dynamically make a query on any tables in the database (populating the Query form using a SQL request) and then display dynamically all columns that exists using an html template (without caring the name of each columns in each table). I am almost capable to make it using a fix database and a fix columns format but lack the knowledge to do it with more adaptative function. Thanks if you can provide some help or guidance.

Here is the Node

[
    {
        "id": "51dc0a4e8246dba1",
        "type": "ui_dropdown",
        "z": "4447f1fa.c7a27",
        "name": "",
        "label": "DB List",
        "tooltip": "",
        "place": "Select option",
        "group": "8e3625ca10f0866b",
        "order": 1,
        "width": 6,
        "height": 1,
        "passthru": true,
        "multiple": false,
        "options": [
            {
                "label": "table1",
                "value": "table1",
                "type": "str"
            },
            {
                "label": "table2",
                "value": "table2",
                "type": "str"
            },
            {
                "label": "table3",
                "value": "table3",
                "type": "str"
            }
        ],
        "payload": "",
        "topic": "DB_name",
        "topicType": "str",
        "className": "",
        "x": 580,
        "y": 820,
        "wires": [
            [
                "7e6d3ab8d5b1e854"
            ]
        ]
    },
    {
        "id": "7e6d3ab8d5b1e854",
        "type": "function",
        "z": "4447f1fa.c7a27",
        "name": "Query Builder",
        "func": "\nvar topic=msg.topic;\nvar payload=msg.payload;\n/////////////////////////////\nif (topic==\"DB_name\")\ndata.table=msg.payload; \n////////////////////////////\n\n    var query=\"\";\n/////////////////////////////\nif(topic==\"submit\")\n\n\nquery=\"SELECT creation_date as col1, name_table1 as col2, description_table1 as col3 FROM \" + data.table;\n\n    \nmsg.payload=query;\nreturn;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 810,
        "y": 820,
        "wires": [
            [
                "4b13afba042bfa5e",
                "5e66eef3629fc25e"
            ]
        ]
    },
    {
        "id": "4b13afba042bfa5e",
        "type": "postgresql",
        "z": "4447f1fa.c7a27",
        "name": "Read Data",
        "query": "{{ msg.payload }}",
        "postgreSQLConfig": "0a602bea5bc68f3e",
        "split": false,
        "rowsPerMsg": "100",
        "outputs": 1,
        "x": 1060,
        "y": 820,
        "wires": [
            [
                "5e66eef3629fc25e",
                "faf458afa373a57d"
            ]
        ]
    },
    {
        "id": "faf458afa373a57d",
        "type": "ui_template",
        "z": "4447f1fa.c7a27",
        "group": "bf26ebd359905ce9",
        "name": "HTML template",
        "order": 1,
        "width": 0,
        "height": 0,
        "format": "<style>\ntable\n{\n    background:grey;\n}\n.main\n{\n    height:500px;\n}\n</style>\n<div class=\"main\">\n<table style=\"width:100%\">\n  <tr>\n    <th>Column1</th> \n    <th>Column2</th>\n    <th>Column3</th> \n\n  \n  </tr>\n  <tr ng-repeat=\"x in msg.payload | limitTo:100\">\n    <td>{{msg.payload[$index].col1}}</td>\n    <td>{{msg.payload[$index].col2}}</td>\n    <td>{{msg.payload[$index].col3}}</td> \n</tr>\n</table>\n</div>",
        "storeOutMessages": true,
        "fwdInMessages": true,
        "resendOnRefresh": false,
        "templateScope": "local",
        "className": "",
        "x": 1290,
        "y": 820,
        "wires": [
            []
        ]
    },
    {
        "id": "dfdaa278ab532efd",
        "type": "inject",
        "z": "4447f1fa.c7a27",
        "name": "show t1",
        "props": [
            {
                "p": "payload"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "SELECT creation_date as col1, name_table1 as col2, description_table1 as col3 FROM public.table1;",
        "payloadType": "str",
        "x": 550,
        "y": 600,
        "wires": [
            [
                "4b13afba042bfa5e"
            ]
        ]
    },
    {
        "id": "c99bf5b882029390",
        "type": "inject",
        "z": "4447f1fa.c7a27",
        "name": "show t2",
        "props": [
            {
                "p": "payload"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "SELECT creation_date as col1, name_table2 as col2, description_table2 as col3 \tFROM public.table2;",
        "payloadType": "str",
        "x": 560,
        "y": 650,
        "wires": [
            [
                "4b13afba042bfa5e"
            ]
        ]
    },
    {
        "id": "07b75af870ee5452",
        "type": "inject",
        "z": "4447f1fa.c7a27",
        "name": "show t3",
        "props": [
            {
                "p": "payload"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "SELECT creation_date as col1, name_table3 as col2, description_table3 as col3 \tFROM public.table3;",
        "payloadType": "str",
        "x": 560,
        "y": 710,
        "wires": [
            [
                "4b13afba042bfa5e"
            ]
        ]
    },
    {
        "id": "be228c26f3961137",
        "type": "ui_button",
        "z": "4447f1fa.c7a27",
        "name": "submit",
        "group": "8e3625ca10f0866b",
        "order": 2,
        "width": 6,
        "height": 1,
        "passthru": false,
        "label": "Submit",
        "tooltip": "",
        "color": "",
        "bgcolor": "",
        "className": "",
        "icon": "",
        "payload": "1",
        "payloadType": "str",
        "topic": "submit",
        "topicType": "str",
        "x": 570,
        "y": 890,
        "wires": [
            [
                "7e6d3ab8d5b1e854"
            ]
        ]
    },
    {
        "id": "5e66eef3629fc25e",
        "type": "debug",
        "z": "4447f1fa.c7a27",
        "name": "",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "payload",
        "targetType": "msg",
        "statusVal": "",
        "statusType": "auto",
        "x": 1300,
        "y": 710,
        "wires": []
    },
    {
        "id": "e45f4f8c9d2336a5",
        "type": "comment",
        "z": "4447f1fa.c7a27",
        "name": "TRIAL SIMPLE WAY",
        "info": "",
        "x": 170,
        "y": 520,
        "wires": []
    },
    {
        "id": "80dec39cc35bcf39",
        "type": "inject",
        "z": "4447f1fa.c7a27",
        "name": "",
        "props": [
            {
                "p": "payload"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": true,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "",
        "payloadType": "str",
        "x": 110,
        "y": 820,
        "wires": [
            [
                "30f46453b3a9690a"
            ]
        ]
    },
    {
        "id": "30f46453b3a9690a",
        "type": "postgresql",
        "z": "4447f1fa.c7a27",
        "name": "LIST ALL public TABLE",
        "query": "SELECT * from pg_catalog.pg_tables WHERE schemaname ='public' ORDER by tablename",
        "postgreSQLConfig": "94962faa5cafebbf",
        "split": false,
        "rowsPerMsg": "100",
        "outputs": 1,
        "x": 330,
        "y": 820,
        "wires": [
            [
                "a6baf3d6043f4ff1",
                "0198ccf055727557"
            ]
        ]
    },
    {
        "id": "a6baf3d6043f4ff1",
        "type": "debug",
        "z": "4447f1fa.c7a27",
        "name": "",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "payload",
        "targetType": "msg",
        "statusVal": "",
        "statusType": "auto",
        "x": 470,
        "y": 990,
        "wires": []
    },
    {
        "id": "0198ccf055727557",
        "type": "ui_template",
        "z": "4447f1fa.c7a27",
        "d": true,
        "group": "bf26ebd359905ce9",
        "name": "",
        "order": 1,
        "width": 0,
        "height": 0,
        "format": "<style>\ntable\n{\n    background:grey;\n}\n.main\n{\n    height:500px;\n}\n</style>\n<div class=\"main\">\n<table style=\"width:100%\">\n  <tr>\n    <th>tablename DATE</th> \n    <th>tablename</th>\n    <th>tableowner</th> \n\n  </tr>\n  <tr ng-repeat=\"x in msg.payload | limitTo:100\">\n    <td>{{msg.payload[$index].schemaname}}</td>\n    <td>{{msg.payload[$index].tablename}}</td>\n    <td>{{msg.payload[$index].tableowner}}</td> \n</tr>\n</table>\n</div>",
        "storeOutMessages": true,
        "fwdInMessages": true,
        "resendOnRefresh": false,
        "templateScope": "local",
        "className": "",
        "x": 520,
        "y": 760,
        "wires": [
            []
        ]
    },
    {
        "id": "8e3625ca10f0866b",
        "type": "ui_group",
        "name": "QUERY",
        "tab": "d18b2f90a4b5b820",
        "order": 1,
        "disp": true,
        "width": "6",
        "collapse": false,
        "className": ""
    },
    {
        "id": "0a602bea5bc68f3e",
        "type": "postgreSQLConfig",
        "name": "Postgres",
        "host": "127.0.0.1",
        "hostFieldType": "str",
        "port": "5432",
        "portFieldType": "num",
        "database": "postgres",
        "databaseFieldType": "str",
        "ssl": "false",
        "sslFieldType": "bool",
        "max": "10",
        "maxFieldType": "num",
        "min": "1",
        "minFieldType": "num",
        "idle": "1000",
        "idleFieldType": "num",
        "connectionTimeout": "10000",
        "connectionTimeoutFieldType": "num",
        "user": "admin",
        "userFieldType": "str",
        "password": "F!berty9817",
        "passwordFieldType": "str"
    },
    {
        "id": "bf26ebd359905ce9",
        "type": "ui_group",
        "name": "Results",
        "tab": "d18b2f90a4b5b820",
        "order": 2,
        "disp": true,
        "width": 14,
        "collapse": false,
        "className": ""
    },
    {
        "id": "94962faa5cafebbf",
        "type": "postgreSQLConfig",
        "name": "DB_local",
        "host": "127.0.0.1",
        "hostFieldType": "str",
        "port": "5432",
        "portFieldType": "num",
        "database": "postgre",
        "databaseFieldType": "str",
        "ssl": "false",
        "sslFieldType": "bool",
        "max": "10",
        "maxFieldType": "num",
        "min": "1",
        "minFieldType": "num",
        "idle": "1000",
        "idleFieldType": "num",
        "connectionTimeout": "10000",
        "connectionTimeoutFieldType": "num",
        "user": "admin",
        "userFieldType": "str",
        "password": "admin",
        "passwordFieldType": "str"
    },
    {
        "id": "d18b2f90a4b5b820",
        "type": "ui_tab",
        "name": "DB_QUERYYYY",
        "icon": "dashboard",
        "order": 16,
        "disabled": false,
        "hidden": false
    }
]

And the CREATE Command for Postgres:

CREATE TABLE IF NOT EXISTS public.table1
(
    "ID" bigint NOT NULL,
    creation_date timestamp without time zone DEFAULT now(),
    name_table1 character varying COLLATE pg_catalog."default",
    description_table1 character varying COLLATE pg_catalog."default",
    CONSTRAINT "Table1_pkey" PRIMARY KEY ("ID")
)

TABLESPACE pg_default;

ALTER TABLE IF EXISTS public.table1
    OWNER to postgres;

CREATE TABLE IF NOT EXISTS public.table2
(
    id2 bigint NOT NULL DEFAULT nextval('table2_id2_seq'::regclass),
    creation_date timestamp with time zone,
    name_table2 character varying COLLATE pg_catalog."default",
    description_table2 character varying COLLATE pg_catalog."default",
    CONSTRAINT table2_pkey PRIMARY KEY (id2)
)

TABLESPACE pg_default;

ALTER TABLE IF EXISTS public.table2
    OWNER to postgres;

-- Table: public.table3

-- DROP TABLE IF EXISTS public.table3;

CREATE TABLE IF NOT EXISTS public.table3
(
    id3 bigint NOT NULL,
    creation_date timestamp with time zone,
    name_table3 character varying COLLATE pg_catalog."default",
    description_table3 character varying COLLATE pg_catalog."default",
    "Another_col_different_from other_table" character varying COLLATE pg_catalog."default",
    CONSTRAINT table3_pkey PRIMARY KEY (id3)
)

TABLESPACE pg_default;

ALTER TABLE IF EXISTS public.table3
    OWNER to postgres;

This should take any array and format a table, you can set limit with msg.limit index 0 is limit, and index 1 is to begin from

[{"id":"dfdaa278ab532efd","type":"inject","z":"bf9e1e33.030598","name":"show t1","props":[{"p":"payload"},{"p":"limit","v":"[2,1]","vt":"json"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"[{\"one\":1,\"two\":1},{\"one\":2,\"two\":2},{\"one\":3,\"two\":3},{\"one\":4,\"two\":4}]","payloadType":"json","x":510,"y":1420,"wires":[["faf458afa373a57d"]]},{"id":"faf458afa373a57d","type":"ui_template","z":"bf9e1e33.030598","group":"bf26ebd359905ce9","name":"HTML template","order":1,"width":0,"height":0,"format":"<style>\ntable\n{\n    background:grey;\n}\n.main\n{\n    height:500px;\n}\n</style>\n<div class=\"main\">\n<table style=\"width:100%\">\n  <tr>\n    <th ng-repeat=\"(key, val) in msg.payload[0]\">{{key}}</th> \n  </tr>\n  <tr ng-repeat=\"x in msg.payload | limitTo : msg.limit[0] : msg.limit[1]\">\n    <td ng-repeat=\"val in x\">{{val}}</td>\n </tr>\n</table>\n</div>","storeOutMessages":true,"fwdInMessages":true,"resendOnRefresh":false,"templateScope":"local","className":"","x":800,"y":1500,"wires":[["5e66eef3629fc25e"]]},{"id":"5e66eef3629fc25e","type":"debug","z":"bf9e1e33.030598","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":1050,"y":1480,"wires":[]},{"id":"c99bf5b882029390","type":"inject","z":"bf9e1e33.030598","name":"show t2","props":[{"p":"payload"},{"p":"limit","v":"[4,0]","vt":"json"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"[{\"one\":1,\"two\":1,\"three\":1},{\"one\":2,\"two\":2,\"three\":2},{\"one\":3,\"two\":3,\"three\":3},{\"one\":4,\"two\":4,\"three\":4}]","payloadType":"json","x":520,"y":1470,"wires":[["faf458afa373a57d"]]},{"id":"bf26ebd359905ce9","type":"ui_group","name":"Results","tab":"d18b2f90a4b5b820","order":2,"disp":true,"width":14,"collapse":false,"className":""},{"id":"d18b2f90a4b5b820","type":"ui_tab","name":"DB_QUERYYYY","icon":"dashboard","order":16,"disabled":false,"hidden":false}]

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.