Il n'y a rien de mal avec votre requête. C'est votre environnement.
Problème
MySqlGrammar
traduit le field->key
notation dans les noms de champs (côté Laravel) dans field->'$.key'
-style extractions (côté MySQL) :
/**
* Wrap the given JSON selector.
*
* @param string $value
* @return string
*/
protected function wrapJsonSelector($value)
{
$path = explode('->', $value);
$field = $this->wrapValue(array_shift($path));
$path = collect($path)->map(function ($part) {
return '"'.$part.'"';
})->implode('.');
// Here:
return sprintf('%s->\'$.%s\'', $field, $path);
}
Je viens de confirmer que MariaDB ne supporte pas le ->
opérateur d'extraction
comme alias du JSON_EXTRACT()
fonction. Cependant, la même requête fonctionne sur un serveur MySQL 5.7 vanilla.
En supposant ce test
tableau :
╔════╤══════════════════╗
║ id │ payload ║
╟────┼──────────────────╢
║ 1 │ {"a": 1, "b": 2} ║
╚════╧══════════════════╝
Une requête qui utilise le ->
opérateur d'extraction :
SELECT payload->"$.b" FROM test;
échoue contre MariaDB 10.2.8 alors qu'il donne un 2
correct contre un serveur MySQL 5.7.19.
Solutions
La bonne solution dépend de ce que vous utilisez en production.
Remplacer MariaDB
Si vous utilisez MySQL, remplacez MariaDB par MySQL dans votre environnement de développement. Sur une machine macOS gérée par homebrew, ce serait aussi simple que :
brew services stop mysql
brew uninstall mariadb
brew install mysql
brew services start mysql
vos données resteront intactes.
Réécrivez vos requêtes
Cependant, si vous utilisez MariaDB en production, vous devez réécrire vos requêtes pour utiliser JSON_EXTRACT()
fonctionner comme Elias déjà mentionné
. Comme vous pouvez le voir, vous devez être beaucoup plus verbeux avec l'API Laravel.
La requête ci-dessus serait :
SELECT JSON_EXTRACT(payload, "$.b") FROM test;