Получение BYTEA из PostgreSQL в Sails.js
У меня есть проблема в работе с типом PostgreSQL BYTEA в Sails.js.
Определение таблицы (да, странно создавать двоичные 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.js, используя node-postgres (pg), результат содержит Node Buffer с 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.
Я вижу два варианта решения этой ситуации:
- Как-то, чтобы предотвратить конвертацию буфера в Waterline и сделать конвертацию самостоятельно.
- Чтобы захватить вывод Waterline и преобразовать его в контроллеры.
Второй вариант кажется менее эффективным, потому что к исходным данным добавляется большой "родительский", и было бы два преобразования Buffer->Waterline->MyFormat вместо простого Buffer->MyFormat.
1 ответ
Первое решение, которое я нашел, основано на идее переопределить функцию Waterline Model на JSON ( https://github.com/balderdashy/waterline).
Я написал функцию преобразования:
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;
}
};
Он работает нормально, но мне кажется, что должен быть менее дорогой метод (ватерлинии преобразует оригинальный буфер в объект, затем я преобразую его в массив, затем в буфер и затем в строку).