2017-11-21 18 views
0

次のコードでは、結果が配列で、時にはオブジェクトになることがあります。空の場合でも配列を受け取りたい私のビジネス・オブジェクト内のknexの選択で予期しない動作が発生しました

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

それは

[{ userId: 1, id: 1 ...を返されたら、私は応答

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

を待つ - 私はこれをしたい

、それは

{ userId: 1, id: 1 ...を返さ次回 - これをしたくない

何が起こっていて、どうすれば配列を返すことができますか?


更新#1

今では、単一の結果を返します。


更新#2

それは悪いから悪化しに行ってきました。

他の基本機能が正しく動作しません。 Knexは最初のパラメータセットでのみ動作し、他のすべてに対して失敗します。

たとえば、高速サーバーが再起動され、userId:1およびpId:1の要求を送信すると、それは機能します。同じパラメータで同じリクエストを繰り返すと動作します。しかし、パラメータ(userIdまたはpId)を別の有効なセットに変更すると、失敗します。他のパラメータを試す前にエクスプレスサーバを再起動する必要があります。私は私のアプリと郵便配達員でこれをテストしました。

私knex設定が問題

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

更新#5 シングルである場合には

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'); 
    } 
}); 

アップデート#4

を次のように私の急行コードが見えますコードページSomeObj

id userId 
1 1 
2 2 
3 2 

なし2番目のクエリを実行することができない

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

コードサンプル/ PG DBに

(のみ高速セットアップを欠落)。私が接続を閉じるために簡単なものがないかどうかわかりません。


更新#6

私はknexが私をいじりさ誓います。私が何かをしようとするたびに(そして、私の新しい入力のために変更が確定したことを確認するために元に戻す)、異なる応答があります。これで、res1とres2の両方が最初の要求に対して正しい結果を返しますが、2番目の要求は失敗します。


更新#7

は、runkit例:https://runkit.com/tristargod/runkit-npm-knex

それは、最初の要求のために動作しますが、特急サーバー上の他のすべての要求のために失敗しました。


更新#8

詳細はhttps://github.com/tgriesser/knex/issues/2346#issuecomment-346757344を参照してください。ありがとうミカエル!

+0

複数のレコードの場合は配列を、1つのレコードの場合はオブジェクトを返します。 – Vatsal

+0

@Vatsal一度だけ、単一のオブジェクトを持つ配列が返されました。私がそれを解決できない場合、それは私の回避策になります。なぜ私はそれが一貫していない得るか分からない。 – SILENT

+0

完全なコード例を1つ作成して、初期化とすべての問題を確認してください。そこからのシングルスニペットでは十分ではありません。 –

答えて

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

常に結果の配列を返す必要があります。この例では表示されていない何か別のことをしています。

例コード:#7

tldrを更新TO https://runkit.com/embed/kew7v2lwpibn

RESPONSE。 Knexクエリビルダは変更可能ですので、再利用する場合は.clone()が必要です。 https://runkit.com/mikaelle/5a17c6d99cd063001284a20a

ニースたとえば、あなたがクエリの間にクローニングすることなく、同じクエリビルダを複数回再利用されている問題

を見つけるのは簡単だったことから。 DEBUG=knex:*環境変数を設定してコードを実行すると、最初の呼び出し後に作成されたクエリが正しくないことがわかります。

const GetAll = async userId => SQL.clone().where({ userId }).select(
    'id', 
    'userId', 
); 
const GetById = async (userId, id) => SQL.clone().where({ userId, id }).first(
    'id', 
    'userId', 
); 
関連する問題