sql >> Databasteknik >  >> RDS >> Mysql

Laravels frågebyggare JSON-väljare `fält->nyckel` orsakar syntaxfel

Det är inget fel på din fråga. Det är din miljö.

Problem

Laravels MySqlGrammar översätter field->nyckeln notation i fältnamn (på Laravel-sidan) till field->'$.key' -stilsextraktioner (på MySQL-sidan):

/**
 * 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);
}

Jag har precis bekräftat att MariaDB inte stöder -> extraktionsoperatör som ett alias till JSON_EXTRACT() fungera. Men samma fråga fungerar mot en vanilla MySQL 5.7-server.

Förutsatt detta test tabell:

╔════╤══════════════════╗
║ id │ payload          ║
╟────┼──────────────────╢
║  1 │ {"a": 1, "b": 2} ║
╚════╧══════════════════╝

En fråga som använder -> extraktionsoperatör:

SELECT payload->"$.b" FROM test;

misslyckas mot MariaDB 10.2.8 medan det ger en korrekt 2 mot en MySQL 5.7.19-server.

Lösningar

Den rätta lösningen beror på vad du använder i produktionen.

Ersätt MariaDB

Om du använder MySQL, ersätt MariaDB med MySQL i din utvecklingsv. På en macOS-maskin som hanteras av homebrew skulle det vara så enkelt som:

brew services stop mysql
brew uninstall mariadb
brew install mysql
brew services start mysql

din data kommer att förbli intakt.

Skriv om dina frågor

Men om du använder MariaDB i produktionen måste du skriva om dina frågor för att använda JSON_EXTRACT() fungera som Elias redan nämnd . Som du kan se måste du vara mycket mer utförlig med Laravel API.

Ovanstående fråga skulle vara:

SELECT JSON_EXTRACT(payload, "$.b") FROM test;


  1. Hur arbetar man med PGpoint för geolokalisering med PostgreSQL?

  2. PG::DuplicateTable:FEL:relationsinlägg finns redan

  3. I Oracle AS fungerar inte aliaset

  4. Använda DateTime i en SqlParameter för lagrad procedur, formatfel