Non c'è niente di sbagliato nella tua domanda. È il tuo ambiente.
Problema
MySqlGrammar
traduce il campo->chiave
notazione nei nomi dei campi (sul lato Laravel) in field->'$.key'
-stile estrazioni (lato 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);
}
Ho appena confermato che MariaDB non supporta ->
operatore di estrazione
come alias per JSON_EXTRACT()
funzione. Tuttavia, la stessa query funziona su un server MySQL 5.7 vanilla.
Assumendo questo test
tabella:
╔════╤══════════════════╗
║ id │ payload ║
╟────┼──────────────────╢
║ 1 │ {"a": 1, "b": 2} ║
╚════╧══════════════════╝
Una query che utilizza ->
operatore di estrazione:
SELECT payload->"$.b" FROM test;
fallisce contro MariaDB 10.2.8 mentre restituisce un 2
corretto contro un server MySQL 5.7.19.
Soluzioni
La soluzione giusta dipende da cosa stai usando in produzione.
Sostituisci MariaDB
Se stai usando MySQL, sostituisci MariaDB con MySQL nel tuo ambiente di sviluppo. Su una macchina macOS gestita da homebrew, sarebbe facile come:
brew services stop mysql
brew uninstall mariadb
brew install mysql
brew services start mysql
i tuoi dati rimarranno intatti.
Riscrivi le tue domande
Tuttavia, se stai utilizzando MariaDB in produzione, devi riscrivere le query per utilizzare JSON_EXTRACT()
funzione come Elia già menzionato
. Come puoi vedere, devi essere molto più dettagliato con l'API di Laravel.
La query precedente sarebbe:
SELECT JSON_EXTRACT(payload, "$.b") FROM test;