I have two tables in a one-to-many relation, created a while ago, not very well thought out.
CREATE TABLE DATA_CONNECTION ( ID bigint(20) NOT NULL, OWNER_ID bigint(20) NOT NULL, PROTOCOL_ID bigint(20) NOT NULL, CONNECTION_METHOD smallint(6) NOT NULL, ADDRESS varchar(255), PORT INTEGER, USERNAME varchar(255), PASSWORD varchar(255), FILE_ENCRYPTION_PASSWORD varchar(255), SECONDARY_PASSWORD varchar(255), HOST_KEY varchar(255), ENCRYPTION_TYPE varchar(255), PUBLIC_KEY_FILE_NAME varchar(255), PRIVATE_KEY_FILE_NAME varchar(255), DATA_FILE_NAME_REGEX varchar(255), METADATA_FILE_NAME_REGEX varchar(255), REMOTE_FILE_NAME_REGEX varchar(255), TIME_ZONE varchar(255), IS_ENABLED tinyint(1) NOT NULL DEFAULT 0, PRIMARY KEY (ID), CONSTRAINT FK_OWNER_ID FOREIGN KEY (OWNER_ID) REFERENCES USER (ID) ON DELETE CASCADE, CONSTRAINT FK_PROTOCOL_ID FOREIGN KEY (PROTOCOL_ID) REFERENCES PROTOCOL (ID) ON DELETE RESTRICT ); CREATE TABLE DATA_CONNECTION_FRAGMENT ( ID bigint(20) NOT NULL, DATA_CONNECTION_ID bigint(20) NOT NULL, NAME varchar(255), AUTH varchar(255), IS_ENABLED tinyint(1), PRIMARY KEY (ID), CONSTRAINT FK_DATA_CONNECTION_ID FOREIGN KEY (DATA_CONNECTION_ID) REFERENCES DATA_CONNECTION (ID) ON DELETE CASCADE ); The problem is that a many of the fields in DATA_CONNECTION are optional. Depending on the PROTOCOL_ID and the CONNECTION_METHOD, some are used and the others are null. I would like to just have a CONNECTION_DETAILS column as a json type, including the DATA_CONNECTION_FRAGMENT table. Like this.
CREATE TABLE DATA_INTEGRATION ( ID bigint(20) NOT NULL, OWNER_ID bigint(20) NOT NULL, PROTOCOL_ID bigint(20) NOT NULL, CONNECTION_METHOD smallint(6) NOT NULL, IS_ENABLED tinyint(1) NOT NULL DEFAULT 0, CONNECTION_DETAILS JSON, -- Something like this {address: string, password: string, fragments: [{name: string, auth: string}, ...etc], ...etc} CONSTRAINT FK_OWNER_ID FOREIGN KEY (OWNER_ID) REFERENCES USER (ID) ON DELETE CASCADE, CONSTRAINT FK_PROTOCOL_ID FOREIGN KEY (PROTOCOL_ID) REFERENCES PROTOCOL (ID) ON DELETE RESTRICT ); So, is there any way to migrate the data with only a sql command? Something like this maybe?
INSERT INTO DATA_INTEGRATION ( ID, PROTOCOL_ID, CONNECTION_METHOD, OWNER_ID, IS_ENABLED, CONNECTION_DETAILS ) SELECT C.ID, C.PROTOCOL_ID, C.CONNECTION_METHOD, C.OWNER_ID, C.IS_ENABLED, JSON_OBJECT ( 'address', C.ADDRESS, 'port', C.PORT, 'username', C.USERNAME, 'password', C.PASSWORD, 'secondaryPassword', C.SECONDARY_PASSWORD, 'hostKey', C.HOST_KEY, 'encryptionType', C.ENCRYPTION_TYPE, 'publicKeyFileName', C.PUBLIC_KEY_FILE_NAME, 'privateKeyFileName', C.PRIVATE_KEY_FILE_NAME, 'dataFilenameRegex', C.DATA_FILENAME_REGEX, 'metadataFilenameRegex', C.METADATA_FILENAME_REGEX, 'remoteFilenameRegex', C.REMOTE_FILENAME_REGEX, 'timeZone', C.TIME_ZONE, 'fragments', JSON_ARRAYAGG(JSON_OBJECT( 'name', F.NAME, 'auth', F.AUTH, 'isEnabled', F.IS_ENABLED )) ) FROM DATA_CONNECTION C JOIN DATA_CONNECTION_FRAGMENT F ON F.DATA_CONNECTION_ID = C.ID; The above isn't working for me, but I'm not sure what I can do to fix it. It only returns one row. Maybe the JSON_ARRAYAGG is breaking it? Maybe I'm not using the right kind of JOIN?
The existing tables have quite a small number of records, so I'm not worried about stressing the db with this.
Thanks!