
Ce problème de création de base de données de données n’est pas spécifique à Symfony ni même à Doctrine. Cette erreur est une erreur SQL signifiant que votre base de données ne connaît pas le type JSON.
Création d’un champ de type JSON en base de données
J’ai lancé la commande suivante sur Symfony me permettant de créer le schéma de ma base de données (mes tables).
php bin/console doctrine:schema:create
Pour ce faire j’utilise Doctrine, j’avais la variable annotée suivante dans mon entité.
/**
* @ORM\Column(type="json")
*/
private $roles= [];
Lorsque la commande ci-dessus était exécutée, on obtenait l’erreur suivante :
SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MariaD B server version for the right syntax to use near 'JSON NOT NULL, password VARCHAR(255) NOT NULL, UNIQUE INDEX UNIQ_8D93D649E7927C7' at line 1
La version longue de cette erreur :
Schema-Tool failed with Error 'An exception occurred while executing 'CREATE TABLE user (id INT AUTO_INCREMENT NOT NULL, email VARCHAR(180) NO T NULL, roles JSON NOT NULL, password VARCHAR(255) NOT NULL, UNIQUE INDEX UNIQ_8D93D649E7927C74 (email), PRIMARY KEY(id)) DEFAULT CHARACTER SE T utf8mb4 COLLATE utf8mb4_unicode_ci ENGINE = InnoDB': SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MariaD B server version for the right syntax to use near 'JSON NOT NULL, password VARCHAR(255) NOT NULL, UNIQUE INDEX UNIQ_8D93D649E7927C7' at line 1 ' while executing DDL: CREATE TABLE user (id INT AUTO_INCREMENT NOT NULL, email VARCHAR(180) NOT NULL, roles JSON NOT NULL, password VARCHAR(2 55) NOT NULL, UNIQUE INDEX UNIQ_8D93D649E7927C74 (email), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci ENGINE = I nnoDB
Serveur de base de données pas à jour
La base de données m’indique qu’elle ne connaît pas le type « JSON », or il existe bel et bien :
- A partir de MariaDB 10.2.7 : https://mariadb.com/kb/en/library/json-data-type/
- A partie de MySQL 5.7.8 : https://dev.mysql.com/doc/refman/5.7/en/json.html
Je vérifie donc sur ma machine le serveur de base de données utilisé :
alex@antergos:~$ mysql --version mysql Ver 15.1 Distrib 10.1.36-MariaDB, for Linux (x86_64) using readline 5.1
MariaDB 10.1.36 < MariaDB 10.2.7, le type de colonne JSON n’a pas encore été implémenté.
Pourtant étant sur Antergos lui même basé sur ArchLinux réputé pour avoir les paquets les plus à jour dans ses dépôts, je suis étonné de constater que ce ne l’est pas.
Solution 1 : Configurer Doctrine pour utiliser le bon type
Sur mon projet Symfony, j’ai du spécifier ma version de MySQL pour que Doctrine puisse utiliser le bon type
doctrine:
dbal:
...
server_version: '5.6'
Cette solution est adéquat si jamais vous n’avez pas la main sur votre serveur de base de données.
Solution 2 : Mettre sa base de données à jour pour supporter le type JSON
Tout simplement, il faut mettre à jour votre serveur de base de données MySQL si vous voulez pouvoir utiliser le type de donnée JSON dans vos colonnes.
Si vous êtes chez un prestataire, demandez-lui de le faire pour vous, mais pensez à faire vos sauvegardes au cas où.
Pour sauvegarder toutes ses base de données avant la mise à jour :
$ mysqldump -u root -p --all-databases > databases.sql
https://stackoverflow.com/questions/9497869/export-and-import-all-mysql-databases-at-one-time
Philippe V
Une solution plus simple est de spécifier la version du serveur SQL utilisée via l’attribut `server_version` de la configuration de Doctrine.
De fait Doctrine adaptera se génération de schéma
• Lien vers le commentaire
Philippe V
(cf https://www.doctrine-project.org/projects/doctrine-dbal/en/2.9/reference/configuration.html#automatic-platform-version-detection )
• Lien vers le commentaire
Alex Soyer Auteur(e) de l'article
Hello,
Tu as tout à fait raison. A l’époque où j’ai écrit cet article je ne connaissais pas cette astuce.
Merci à toi 🙂
• Lien vers le commentaire
seb j
tu pourrais donner plus de précision de comment pouvoir le faire, j’ai ce problème et je cherche à le résoudre..
• Lien vers le commentaire
Alex Soyer Auteur(e) de l'article
Peux-tu préciser sur quelle techno tu travailles ? C’est quoi ta stack ?
• Lien vers le commentaire
Loenix
J’ai ce soucis alors que sous la config dbal, j’ai
server_version: « mariadb-10.1.44 »
Pour autant, doctrine n’adapte pas le code en conséquence.
• Lien vers le commentaire