#ruby-on-rails #postgresql #rails-activerecord
#ruby-on-rails #postgresql #rails-activerecord
Вопрос:
Агрегаты Postgres, такие как SUM(foo), возвращают строку, даже если foo является целым числом.
Как мне преобразовать сумму в целое число, чтобы результирующий массив отношений содержал целое число, а не строку?
Я попытался привести его с помощью ::integer
Widget.select(«СУММА (баллов) как итоговые баллы:: целое число, агент, компания»)
но postgres выдает ошибку PG::Error: ERROR: syntax error at or near "::"
Кажется, должен быть какой-то способ сообщить rails — за исключением перебора каждого возвращаемого элемента массива — что СУММА INT равна INT ?
Ответ №1:
Это может быть просто адаптер ActiveRecord . Однако я не совсем уверен в этом. Но я думаю, что когда вы переходите к API-интерфейсам уровня выбора, он просто возвращает строки, потому что это то, что он фактически считывает из базы данных. Когда вы используете API более высокого уровня, я думаю, он знает, как преобразовать его обратно в типы Ruby, потому что он знает о вашей схеме там.
У меня возникли проблемы с воспроизведением вашего запроса выше, но я сделал следующее:
Widget.connection.select_rows("SELECT sum(id) FROM widgets")
Это вернуло:
[
[0] [
[0] "887"
]
]
А если я использую API более высокого уровня:
2.0.0-p353 :034 > Widget.sum('id')
D, [2014-06-24T15:34:52.644852 #95176] DEBUG -- : (0.5ms) SELECT SUM("widgets."."id") AS sum_id FROM "widgets"
887
На данный момент он выдает мне целочисленный тип в моей консоли. Поэтому я подозреваю, что в Postgres нет ничего плохого, но вам может потребоваться преобразовать в собственные типы самостоятельно, когда вы используете ActiveRecord select API.
Комментарии:
1. В принципе, вы правы. AR на самом деле ничего не понимает в типах из SQL, которые он не пишет сам.
2. да, postgres возвращает строку. похоже, должно быть возможно каким-то образом ПРЕОБРАЗОВАТЬ это в int в запросе. Прямо сейчас я использую .map() для итеративного преобразования его в int, но суммирование целых чисел — это такая фундаментально базовая операция, что трудно поверить, что это не простая операция запроса.
3. Нет, вы смотрите на это неправильно. Когда вы используете некоторые API-интерфейсы более низкого уровня для передачи вашего запроса в postgres, это фактически похоже на ввод текста в
psql
консоль. Postgres знает, что это целое число, но по сути это просто сброс больших двоичных объектов текста так же, как вы получаете в psql. Rails не анализирует передаваемый вами SQL, поэтому он не знает, какие типы ожидать в ответе, поэтому он не может автоматически конвертировать, как это обычно делается. Так что вам решать сделать это преобразование самостоятельно. Вы не можете просто выполнить ПРИВЕДЕНИЕ в Postgresql; postgres знает, что это целое число. Rails этого не делает.