Sails.js -postgresql возвращает строковое значение вместо целого числа для полей bigint

Мы переносим проект с PHP на Node.js, используя Sails.js в качестве бэкэнд-фреймворка. Мы не можем изменить нашу базу данных и должны использовать существующую базу данных для этого проекта.

Если я оставлю migrate: "alter" для вновь созданной модели, Sails по умолчанию сохранит поле id как целое число.

Однако для нашей существующей базы данных id полей в основном bigint. Итак, я определил migrate: "safe" и приступил к созданию модели.

Теперь проблема, с которой я сталкиваюсь, заключается в том, что когда маршруты blueprint возвращают результат, значение столбца id, которое должно быть возвращено в виде числа, вместо этого возвращается в виде строки. Вот пример:

[
  {
    "starttime": "07:00:00",
    "endtime": "14:00:00",
    "id": "1"
  },
  {
    "starttime": "14:00:00",
    "endtime": "22:00:00",
    "id": "2"
  },
  {
    "starttime": "22:00:00",
    "endtime": "07:00:00",
    "id": "3"
  }
]

Как я могу решить эту проблему?

Вот моя модель:

module.exports = {
  tableName: "timeslots",
  autoCreatedAt: false,
  autoUpdatedAt: false,
  attributes: {
    starttime: { type: "string", required: true },
    endtime: { type: "string", required: true }
  }
};

А вот определение таблицы postgresql

                                              Table "public.timeslots"
  Column   |  Type  |                       Modifiers                        | Storage  | Stats target | Description 
-----------+--------+--------------------------------------------------------+----------+--------------+-------------
 id        | bigint | not null default nextval('timeslots_id_seq'::regclass) | plain    |              | 
 starttime | text   | not null                                               | extended |              | 
 endtime   | text   | not null                                               | extended |              | 
Indexes:
    "idx_43504_primary" PRIMARY KEY, btree (id)
Referenced by:
    TABLE "doctortimeslot" CONSTRAINT "doctortimeslot_ibfk_2" FOREIGN KEY (timeslot_id) REFERENCES timeslots(id) ON UPDATE CASCADE ON DELETE CASCADE

person Mandeep Singh    schedule 03.10.2015    source источник


Ответы (2)


Waterline становится странным с типами данных, в которые он не встроен. Я думаю, что по умолчанию он использует строки, когда не уверен, что делать. На самом деле это не должно иметь значения, поскольку JS автоматически преобразует эти значения в числа в вашем интерфейсе.

Однако, если вам нужно, чтобы это было число, самым простым решением, вероятно, будет переопределение метода toJSON в модели и принудительное преобразование этого значения в целое число.

module.exports = {
  tableName: "timeslots",
  autoCreatedAt: false,
  autoUpdatedAt: false,
  attributes: {
    starttime: { type: "string", required: true },
    endtime: { type: "string", required: true },

    toJSON: function(){
      var obj = this.toObject();
      obj.id = parseInt(obj.id);
      return obj;
    }

  }
};
person Lenny    schedule 03.10.2015
comment
Идеальный! переопределение метода toJSON было бы идеальным решением в моем случае, поскольку API должен использоваться собственными приложениями для Android и iOS. Спасибо! - person Mandeep Singh; 03.10.2015
comment
Каким-либо образом можно переопределить этот метод для всех моделей без явного указания в каждой модели? - person Mandeep Singh; 03.10.2015
comment
Нашел. Указан в файле model.js attributes: { toJSON: function(){ var obj = this.toObject(); obj.id = parseInt(obj.id); return obj; } } - person Mandeep Singh; 03.10.2015
comment
Я не уверен... Если да, то вы бы сделали это в config/models.js. Я не знаю, можете ли вы определить атрибуты там или нет. - person Lenny; 03.10.2015

В качестве альтернативы вы можете использовать https://github.com/mirek/node-pg-safe-numbers, которые решают именно эту проблему, делегируя вам небезопасную обработку (когда число не соответствует пределу 2 ^ 53 javascript) - где вы можете вернуть проанализированное значение, строку, ноль, выдать ошибку или сделать что-то еще .

Во многих случаях вы можете использовать автоматический анализ, предоставляемый библиотекой, и в небезопасном обработчике просто вернуть исходное строковое значение. Затем в коде, который использует числа выше 2 ^ 53 (т.е. случайные большие числа), всегда приводится к строке, и все будет в порядке.

person Mirek Rusin    schedule 29.10.2015