2017-11-21 15 views
0

Für den folgenden Code, bekomme ich ein Ergebnis, das manchmal ein Array und manchmal ein Objekt ist. Ich möchte das Array erhalten, auch wenn es leer ist.Unerwartetes Verhalten mit Knex Select

export const GetByPId = async (userId, pId) => knex('table1').where({ userId, pId }).select(
    'userId', 
    'pId', 
    'id', 
    'created', 
    'updated', 
); 

In meinem Business-Objekt, erwarte ich die Antwort

static async LoadByPId(userId, pId) { 
    const data = await GetByPId(userId, pId); 
    console.log(`result ${JSON.stringify(data)}`); 
} 

Sobald es

zurück

[{ userId: 1, id: 1 ... - Ich möchte diese

und es das nächste Mal wieder

{ userId: 1, id: 1 ... - Ich will das nicht

Was passiert und wie kann ich immer ein Array zurückgeben?


Update # 1

es gibt jetzt nur ein einziges Ergebnis.


Update # 2

Es ging immer schlechter.

Jetzt funktionieren meine anderen grundlegenden Funktionen nicht richtig. Knex funktioniert nur mit dem ersten Satz von Parametern und schlägt für alles andere fehl.

Zum Beispiel, wenn der Express-Server neu gestartet wurde und eine Anfrage für userId: 1 und pId: 1, es funktioniert. Wenn ich dieselbe Anfrage mit denselben Parametern wiederhole, funktioniert es. Aber wenn ich die Parameter (dh userId oder pId) zu einem anderen gültigen Satz ändere, schlägt es fehl. Ich muss den Express-Server neu starten, bevor ich andere Parameter ausprobiere. Ich habe das auf meiner App und meinem Postboten getestet.

Mein Express Code sieht wie folgt

router.post('/list', auth, async (req, res) => { 
    try { 
    const biz= await BizObj.LoadByPId(req.user.id, req.body.pId); 
    res.json(biz); 
    } catch (ex) { 
    console.log(ex); 
    res.status(400).json('Unauthorized'); 
    } 
}); 

Update # 4

Falls mein Knex Config ist das Problem

development: { 
    client: 'postgresql', 
    connection: { 
     database: 'somedb', 
     user: 'SOMEUSER', 
     password: '', 
     timezone: 'UTC', 
    }, 
    pool: { 
     min: 2, 
     max: 10, 
    }, 
    migrations: { 
     tableName: 'knex_migrations', 
    }, 
    }, 

Update # 5 Einzel Seite des Codes (Nur fehlt Express-Setup)

in pg db/someObj

id userId 
1 1 
2 2 
3 2 

Codebeispiel

import knex from 'knex'; 
import express from 'express'; 

const config = { 
    development: { 
    client: 'pg', 
    connection: { 
     database: 'somedb', 
     user: 'SOMEUSER', 
     password: '', 
     timezone: 'UTC', 
    }, 
    pool: { 
     min: 2, 
     max: 10, 
    }, 
    migrations: { 
     tableName: 'knex_migrations', 
    }, 
    }, 
}; 

const knexed = knex(config.development); 
const SQL = knexed('SomeObj'); 
const GetAll = async userId => SQL.where({ userId }).select(
    'id', 
    'userId', 
); 
const GetById = async (userId, id) => SQL.where({ userId, id }).first(
    'id', 
    'userId', 
); 

class SomeObj { 
    constructor(data, userId) { 
     this.userId = userId; 
     this.id = data.id; 
    } 
    static async LoadAll(userId) { 
     const data = await GetAll(userId); 
     if (!data || data.length === 0) return null; 
     return data.map(r => new SomeObj(r, userId)); 
    } 
    static async Load(userId, id) { 
     const data = await GetById(userId, id); 
     if (!data) return null; 
     return new SomeObj(data, userId); 
    } 
} 

const router = express.Router(); 

router.post('/list', async (req, res) => { 
    try { 
    const res1 = await SomeObj.LoadAll(req.body.id); // works and returns array 
    const res2 = await SomeObj.Load(req.body.id, 2); // fails and returns undefined 
    res.json({ res1, res2 }); 
    } catch (ex) { 
    res.status(401).json(ex); 
    } 
}); 

keine zweite Abfrage ausgeführt werden kann. Ich weiß nicht, ob mir etwas Einfaches fehlt, um die Verbindung zu schließen.


Update # 6

Ich schwöre Knex mit mir verwirren.Jedes Mal, wenn ich etwas versuche (und zur Bestätigung zurückkehren, dass Änderungen aufgrund meiner neuen Eingaben fällig sind), gibt es unterschiedliche Antworten. Nun geben sowohl res1 als auch res2 das korrekte Ergebnis für die erste Anfrage zurück, aber die zweite Anfrage schlägt fehl.


Update # 7

Runkit Beispiel: https://runkit.com/tristargod/runkit-npm-knex

Es läuft für die erste Anforderung aber nicht für alle anderen Anfragen auf Express-Server.


Update # 8

für weitere Details zu https://github.com/tgriesser/knex/issues/2346#issuecomment-346757344 finden. Danke Mikael!

+0

sieht aus wie es ein Array im Falle von mehreren Datensätzen und ein Objekt im Falle von einzelnen Datensatz zurückgibt. Vielleicht können Sie einfach überprüfen, ob (! Array.isArray (Daten) {Daten = [Daten];} nur ein Gedanke :) – Vatsal

+0

@Vatsal Einmal gab es ein Array mit einem einzigen Objekt. Wenn ich es nicht lösen kann, wäre das meine Problemumgehung. Ich verstehe nicht, warum es nicht konsistent ist. – SILENT

+0

Versuchen Sie, einen vollständigen Codebeispiel zu erstellen, mit Initialisierung und allem, damit wir sehen können, was das Problem ist. Einzelne Schnipsel von dort und da sind nicht genug. –

Antwort

2
knex('table1') 
.where({ userId, pId }) 
.select('userId', 'pId', 'id', 'created', 'updated') 

Sollte immer eine Reihe von Ergebnissen zurückgeben. Sie tun etwas anderes falsch, das im Beispiel nicht gezeigt wird.

Beispielcode: https://runkit.com/embed/kew7v2lwpibn

RESPONSE # AKTUALISIEREN 7

TLDR; Knex Query Builder sind veränderbar, daher ist clone() bei der Wiederverwendung notwendig. https://runkit.com/mikaelle/5a17c6d99cd063001284a20a

Nizza Beispiel aus, dass es leicht war, das Problem

Sie Wiederverwendung der gleichen Query Builder mehrfach zu erkennen, ohne sie zwischen den Abfragen klonen. Wenn Sie Ihren Code mit DEBUG=knex:* Umgebungsvariablensatz ausführen würden, würden Sie sehen, dass konstruierte Abfragen nach dem ersten Aufruf nicht korrekt sind.