GraphQL gibt von der MySQL-Join-Abfrage null zurück

Chris Baum

Ich habe ein kleines Node-Projekt (einfache Ratespielbasis für Standorte), um ein React-Frontend zu bedienen. Es verwendet einen Apollo-Server, um Daten aus einer AWS RDS MySQL-Datenbank mit knex als Abfrage-Generator abzurufen. Ich kann erfolgreich Daten aus einer einzelnen Tabelle abrufen, aber wenn die Abfrage einen Join enthält, ist das untergeordnete Objekt in graphql immer null.

Wenn ich lokal auf den Knotenserver zugreife und die Daten nach Vermutungen abfrage, habe ich die Vermutungsdaten , aber die zugehörigen Benutzer- und Fragendaten sind immer null, wie das Bild zeigt.

graphql_issue

Hier ist der Code - Ich habe einen Teil des überschüssigen Codes für die Abfragen entfernt, die einwandfrei funktionieren.

Datenbank

CREATE TABLE `question` (
  `id` int NOT NULL AUTO_INCREMENT,
  `lat` float NOT NULL,
  `lng` float NOT NULL,
  `question` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
);

CREATE TABLE `guess` (
  `id` int NOT NULL AUTO_INCREMENT,
  `lat` float NOT NULL,
  `lng` float NOT NULL,
  `question_id` int NOT NULL,
  `user_id` int NOT NULL,
  PRIMARY KEY (`id`),
  KEY `user_id` (`user_id`),
  KEY `question_id` (`question_id`),
  CONSTRAINT `guess_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`),
  CONSTRAINT `guess_ibfk_2` FOREIGN KEY (`question_id`) REFERENCES `question` (`id`)
);

CREATE TABLE `user` (
  `id` int NOT NULL AUTO_INCREMENT,
  `username` varchar(11) NOT NULL,
  `icon` varchar(11) NOT NULL,
  `score` int NOT NULL DEFAULT '0',
  PRIMARY KEY (`id`)
);

Apollo Server-Anwendung

index.js

const { ApolloServer } = require("apollo-server");
const typeDefs = require("./schema");
const mapDatabase = require("./datasources/map");
const resolvers = require("./resolver");

const knexConfig = {
    client: "mysql",
    connection: {
        host: "my-server",
        user: "my-username",
        password: "my-password",
        database: "db-name",
    },
};

const server = new ApolloServer({
    typeDefs,
    resolvers,
    dataSources: () => ({
        mapDatabase: new mapDatabase(knexConfig),
    }),
});

// The `listen` method launches a web server.
server.listen().then(({ url }) => {
    console.log(`Server ready at ${url}`);
});

schema.js

const { gql } = require("apollo-server");

const typeDefs = gql`
    type User {
        id: ID!
        username: String
        icon: String
        score: Int
    }
    type Question {
        id: ID!
        lat: Float
        lng: Float
        question: String
    }
    type Guess {
        id: ID!
        lat: Float
        lng: Float
        question: Question
        user: User
    }
    type Query {
        guesses(question: Int!): [Guess]
    }
`;

module.exports = typeDefs;

resolver.js

module.exports = {
    Query: {
        guesses: (_, { question }, { dataSources }) =>
            dataSources.mapDatabase.getGuessesByQuestion(question),
    },
};

Datenquellen / map.js

const { SQLDataSource } = require("datasource-sql");

class MapDatabase extends SQLDataSource {
    getGuessesByQuestion(question) {
        return this.knex
            .select("*")
            .from("guess AS g")
            .leftJoin("user AS u", "u.id", "g.user_id")
            .leftJoin("question AS q", "q.id", "g.question_id")
            .where("g.question_id", "=", question);
    }
}

Nur zur Überprüfung der Integrität habe ich die Abfrage in der Datenbank ausgeführt, um sicherzustellen, dass die zugehörigen Ergebnisse vorliegen und alles wie erwartet wiederhergestellt wird.

SELECT * FROM guess g
LEFT JOIN user u ON u.id = g.user_id
LEFT JOIN question q ON a.id = g.question_id
WHERE g.question_id = 1;
Herku

Das Problem ist, dass Ihre Abfrage flache Daten zurückgibt, während Ihre impliziten GraphQL-Resolver eine verschachtelte Objektstruktur erwarten würden. ZB würde knext so etwas zurückgeben:

{
  id: 1,
  lat: 89.4,
  lon: -12.6,
  user_id: 2,
  username: "user",
  icon: "x",
  score: 3
}

Aber Sie würden so etwas brauchen, damit der Resolver "nur funktioniert".

{
  id: 1,
  lat: 89.4,
  lon: -12.6,
  user: {
    id: 2,
    username: "user",
    icon: "x",
    score: 3
  }
}

Denken Sie daran: Wenn Sie keinen Resolver an ein Feld übergeben, wird der Standard-Resolver verwendet, der versucht, auf die Feldnamen-Eigenschaft des Objekts zuzugreifen. Das userFeld hätte also den folgenden Standardauflöser:

parent => parent.user

In der flachen Struktur gibt es kein Feld, daher wird zurückgegeben undefined-> Die Abfrage gibt für das Feld null zurück. In der verschachtelten Struktur wird ein gültiges Benutzerobjekt zurückgegeben.

Sie können das Ergebnis entweder mithilfe von SQL JSON-Funktionen erstellen oder einen benutzerdefinierten Resolver implementieren für Guess.user:

module.exports = {
  Query: {
    guesses: (_, { question }, { dataSources }) =>
      dataSources.mapDatabase.getGuessesByQuestion(question),
  },
  Guess: {
    user: (parent) => ({
      id: parent.user_id,
      username: parent.username,
      icon: parent.icon,
      score: parent.score
    }),
  }
};

Dieser Artikel stammt aus dem Internet. Bitte geben Sie beim Nachdruck die Quelle an.

Bei Verstößen wenden Sie sich bitte [email protected] Löschen.

bearbeiten am
0

Lass mich ein paar Worte sagen

0Kommentare
LoginNach der Teilnahme an der Überprüfung

Verwandte Artikel

Die einfache Abfrage von MySQL gibt null Zeilen zurück

Warum gibt LEFT JOIN von MySQL mit der WHERE-Klausel "NULL" -Datensätze zurück?

Modellklasse, die von der Firebase-Abfrage null zurückgibt (Abfrageergebnis gibt nicht null zurück)

Die Abfrage "Left Join Fetch" von Spring Data gibt null zurück

Die einfache GraphQL-Abfrage "Hallo" gibt NULL zurück

Apollo/Graphql, Postgres - Warum gibt diese Abfrage null zurück?

Warum gibt eine GraphQL-Abfrage null zurück?

Die MySQL Left Join-Abfrage gibt keine Zeilen mit dem Wert Null zurück

Gibt die letzte Zeile in der MySQL-Abfrage vom linken Join zurück

Die Emulation von ROW_NUMBER() in der MariaDB-SQL-Abfrage gibt beim Ausführen der Abfrage null zurück

Der Operator Not IN in MySQL gibt NULL zurück

Die Java MYSQL / JDBC-Abfrage gibt veraltete Daten von der zwischengespeicherten Verbindung zurück

Warum gibt der Query Builder von Codeigniter diese MySQL-Abfrage falsch und zweimal zurück?

Die Abfrage von Linq zu XML gibt null zurück

Postgres gibt [null] anstelle von [] für array_agg der Join-Tabelle zurück

MySQL-Abfrage gibt immer Null zurück

MySql LEFT JOIN gibt nur eine NULL-Zeile aus der anderen Tabelle zurück

Mysql LEFT JOIN mit IS NULL gibt das Nullergebnis zurück

MySQL-Abfrage gibt Spaltennamen in einer durch Kommas getrennten Liste zurück, wobei der Wert null ist

Ruhezustand - Die Abfrage gibt für alle Felder in der Entität null zurück, während dieselbe Abfrage perfekt von db zurückgegeben wird

Die GraphQL-Abfrage gibt sowohl in GraphiQL als auch in der App Null-Objekte aus der JSON-Datenquelle zurück

Nestjs / GraphQL - Playground gibt Null Fehler für Abfrage zurück. Meine Resolver?

Der markerClick () von agm-marker gibt null zurück

Das Konvertieren der Bitmap von Uri gibt null zurück

Der JSON-Typ von PostgreSQL gibt null zurück

Der Aufruf von Firebase-Funktionen gibt null zurück

Der Index von NSDictionary gibt beim Aufruf null zurück

Der Wert von onDataChange gibt null zurück

Der Speicherwert von JpaRepository gibt immer null zurück

TOP Liste

heißlabel

Archiv