Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Alter an existing MySQL column to a JSON data type

I am trying to change a MySQL column from varchar(9000) NULL to the new JSON data type in MySQL 5.7. The column holds valid JSON strings but some values are null. When I try the following:

alter table log modify request json

it fails with the following error:

Invalid JSON text: "The document is empty." at position 0 in value for column '#sql-2f36_168a6.request'

However, when I create a new column:

alter table log add request_json json

and then insert the same data:

update log set request_json=json where request != ''

the new request_json column is updated. How to I modify the existing column to JSON data type and preserve the JSON data without creating a new column?

like image 710
Steve Lloyd Avatar asked Jun 14 '16 12:06

Steve Lloyd


People also ask

How do I add a column to a JSON in MySQL?

CREATE TABLE `book` ( `id` MEDIUMINT(8) UNSIGNED NOT NULL AUTO_INCREMENT, `title` VARCHAR(200) NOT NULL, `tags` JSON DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=INNODB; Note that JSON columns can't have a default value, be used as a primary key, be used as a foreign key, or have an index.

Does MySQL have a JSON column type?

MySQL supports a native JSON data type defined by RFC 7159 that enables efficient access to data in JSON (JavaScript Object Notation) documents. The JSON data type provides these advantages over storing JSON-format strings in a string column: Automatic validation of JSON documents stored in JSON columns.

How do I export data from MySQL to JSON?

Exporting MySQL data to JSON using the CONCAT() and GROUP_CONCAT() functions. Using a combination of CONCAT() and GROUP_CONCAT() functions, data from SQL string can be converted into JSON format. More about the usage of INTO OUTFILE can be found in the How to export MySQL data to CSV article.


1 Answers

12.6 The JSON Data Type

...

  • Automatic validation of JSON documents stored in JSON columns. Invalid documents produce an error.

...

mysql> SHOW CREATE TABLE `log`\G
*************************** 1. row ***************************
       Table: log
Create Table: CREATE TABLE `log` (
  `request` json DEFAULT NULL
) ENGINE=InnoDB
1 row in set (0,00 sec)

mysql> SELECT `request`, JSON_VALID(`request`)
    -> FROM `log`;
+-----------------+-----------------------+
| request         | JSON_VALID(`request`) |
+-----------------+-----------------------+
| {"type": "bug"} |                     1 |
| NULL            |                  NULL |
| NULL            |                  NULL |
+-----------------+-----------------------+
3 rows in set (0,00 sec)

mysql> UPDATE `log`
    -> SET `request` = ''
    -> WHERE `request` IS NULL;
ERROR 3140 (22032): Invalid JSON text: "The document is empty." at position 0 in value for column 'log.request'.

Try:

mysql> DROP TABLE IF EXISTS `log`;
Query OK, 0 rows affected (0,00 sec)

mysql> CREATE TABLE IF NOT EXISTS `log` (
    ->   `request` VARCHAR(9000) NULL
    -> );
Query OK, 0 rows affected (0,01 sec)

mysql> INSERT INTO `log`
    ->   (`request`)
    -> VALUES
    ->   ('{"type": "bug"}'),
    ->   (NULL),
    ->   ('');
Query OK, 3 rows affected (0,00 sec)
Records: 3  Duplicates: 0  Warnings: 0

mysql> SELECT `request`, JSON_VALID(`request`)
    -> FROM `log`;
+-----------------+-----------------------+
| request         | JSON_VALID(`request`) |
+-----------------+-----------------------+
| {"type": "bug"} |                     1 |
| NULL            |                  NULL |
|                 |                     0 |
+-----------------+-----------------------+
3 rows in set (0,00 sec)

mysql> ALTER TABLE `log` MODIFY `request` JSON;
ERROR 3140 (22032): Invalid JSON text: "The document is empty." at position 0 in value for column '#sql-1bab_4.request'.

mysql> UPDATE `log`
    -> SET `request` = NULL
    -> WHERE `request` = '';
Query OK, 1 row affected (0,00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> ALTER TABLE `log` MODIFY `request` JSON;
Query OK, 3 rows affected (0,00 sec)
Records: 3  Duplicates: 0  Warnings: 0

mysql> SELECT `request`, JSON_VALID(`request`)
    -> FROM `log`;
+-----------------+-----------------------+
| request         | JSON_VALID(`request`) |
+-----------------+-----------------------+
| {"type": "bug"} |                     1 |
| NULL            |                  NULL |
| NULL            |                  NULL |
+-----------------+-----------------------+
3 rows in set (0,00 sec)

mysql> SHOW CREATE TABLE `log`\G
*************************** 1. row ***************************
       Table: log
Create Table: CREATE TABLE `log` (
  `request` json DEFAULT NULL
) ENGINE=InnoDB
1 row in set (0,00 sec)
like image 142
wchiquito Avatar answered Sep 28 '22 06:09

wchiquito