No hay nada malo con tu consulta. Es tu entorno.
Problema
MySqlGrammar
traduce el field->key
notación en nombres de campo (en el lado de Laravel) en field->'$.key'
extracciones de estilo (en el lado de 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);
}
Acabo de confirmar que MariaDB no es compatible con ->
operador de extracción
como un alias para el JSON_EXTRACT()
función. Sin embargo, la misma consulta funciona en un servidor MySQL 5.7 estándar.
Asumiendo esta prueba
tabla:
╔════╤══════════════════╗
║ id │ payload ║
╟────┼──────────────────╢
║ 1 │ {"a": 1, "b": 2} ║
╚════╧══════════════════╝
Una consulta que utiliza el ->
operador de extracción:
SELECT payload->"$.b" FROM test;
falla contra MariaDB 10.2.8 mientras produce un 2
correcto contra un servidor MySQL 5.7.19.
Soluciones
La solución correcta depende de lo que esté usando en producción.
Reemplazar MariaDB
Si está utilizando MySQL, reemplace MariaDB con MySQL en su entorno de desarrollo. En una máquina macOS administrada por homebrew, sería tan fácil como:
brew services stop mysql
brew uninstall mariadb
brew install mysql
brew services start mysql
sus datos permanecerán intactos.
Reescribe tus consultas
Sin embargo, si usa MariaDB en producción, debe volver a escribir sus consultas para usar JSON_EXTRACT()
funciona como Elias ya mencionado
. Como puede ver, debe ser mucho más detallado con la API de Laravel.
La consulta anterior sería:
SELECT JSON_EXTRACT(payload, "$.b") FROM test;