Mysql
 sql >> Database >  >> RDS >> Mysql

Il selettore JSON del generatore di query di Laravel `field->key` causa un errore di sintassi

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;