2

Sails.js で PostgreSQL BYTEA 型を処理する際に問題があります。

テーブル定義 (はい、バイナリ PK を作成するのは奇妙ですが、some_data は常に小さいです):

CREATE TABLE data_blobs (
  some_data BYTEA PRIMARY KEY,
  my_date_time TIMESTAMP WITH TIME ZONE NOT NULL);

モデル構成は次のようになります。

module.exports = {
  tableName: 'data_blobs',
  autoCreatedAt: false,
  autoUpdatedAt: false,
  autoPK: false,
  attributes: {
    some_data: {
      type: 'binary',
      primaryKey: true
    },
    my_date_time: 'datetime',
};

node-postgres (pg) を使用して node.js からテーブルをクエリすると、結果には非常に使いやすい some_data を含むノード バッファーが含まれます。

しかし、次のようなコードを使用して Sails.js からテーブルをクエリすると:

DataBlobs.find().then(function(result){
  console.log('Result: ');
  console.log(result);
});

結果は次のようになります。

{
  some_data: 
  { '0': 1,
    '1': 79,
    '2': 95,
    ...
    '19': 216,
    length: 20,
    parent: 
    { '0': 47,
      ...
      '8191': 0 }
  },
  my_date_time: '2015-08-24T10:43:11.959Z'
}

私には、Waterline が Node Buffer を奇妙でまったく役に立たないものに変換しているように思えます (追加の変換なしで)。Waterline のドキュメントにも、sails-postgresql のドキュメントにもない、データ変換に関するドキュメントは見つかりませんでした。

この状況に対処するには、次の 2 つのオプションがあります。

  1. どういうわけか、Waterline が Buffer を変換するのを防ぎ、自分で変換を行うようにします。
  2. Waterline の出力を取得し、コントローラーで変換します。

元のデータに大きな「親」が追加され、単純な Buffer->MyFormat の代わりに Buffer->Waterline->MyFormat の 2 つの変換が行われるため、2 番目のオプションはあまり効果的ではないようです。

4

1 に答える 1

0

私が見つけた最初の解決策は、ウォーターライン モデル関数を JSON にオーバーライドするというアイデアに基づいています ( https://github.com/balderdashy/waterline#model )。

私は変換関数を書きました:

function internalWaterlineBinaryToBase64(waterlineBinaryRepresentation) {
  var temporaryArray = [];
  for(var i = 0, arrLength = waterlineBinaryRepresentation.length; i < arrLength; i++) {
    temporaryArray.push(waterlineBinaryRepresentation[i.toString()]);
  }

  var temporaryBuffer = new Buffer(temporaryArray);

  return temporaryBuffer.toString('base64');
}

そして私のモデルを調整しました:

module.exports = {
  tableName: 'data_blobs',
  autoCreatedAt: false,
  autoUpdatedAt: false,
  autoPK: false,
  attributes: {
    some_data: {
      type: 'binary',
      primaryKey: true
    },
    my_date_time: 'datetime',
    toJSON: function() {
      var obj = this.toObject();

      if(obj.some_data) {
        obj.some_data = internalWaterlineBinaryToBase64(obj.some_data);
      }

      return obj;
    }
};

それは正常に動作しますが、より安価な方法があるべきだと私には思えます (waterline は元の Buffer をオブジェクトに変換し、次にそれを Array に変換し、次に Buffer に変換し、次に String に変換します)。

于 2015-08-26T09:34:17.633 に答える