Na vašem dotazu není nic špatného. Je to vaše prostředí.
Problém
Laravelův MySqlGrammar
přeloží field->key
zápis v názvech polí (na straně Laravelu) do field->'$.key'
-style extrakce (na straně 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);
}
Právě jsem potvrdil, že MariaDB nepodporuje ->
operátor extrakce
jako alias k JSON_EXTRACT()
funkce. Stejný dotaz však funguje proti vanilla serveru MySQL 5.7.
Za předpokladu tohoto test
tabulka:
╔════╤══════════════════╗
║ id │ payload ║
╟────┼──────────────────╢
║ 1 │ {"a": 1, "b": 2} ║
╚════╧══════════════════╝
Dotaz, který používá ->
operátor extrakce:
SELECT payload->"$.b" FROM test;
selže proti MariaDB 10.2.8, zatímco dává správný 2
proti serveru MySQL 5.7.19.
Řešení
Správné řešení závisí na tom, co používáte při výrobě.
Nahradit MariaDB
Pokud používáte MySQL, nahraďte MariaDB ve svém vývojovém prostředí MySQL. Na počítači macOS spravovaném homebrew by to bylo stejně snadné jako:
brew services stop mysql
brew uninstall mariadb
brew install mysql
brew services start mysql
vaše data zůstanou nedotčena.
Přepište své dotazy
Pokud však používáte MariaDB v produkci, musíte své dotazy přepsat tak, aby používali JSON_EXTRACT()
fungovat jako již zmíněný Elias
. Jak vidíte, musíte být s Laravel API mnohem podrobnější.
Výše uvedený dotaz by byl:
SELECT JSON_EXTRACT(payload, "$.b") FROM test;