Как запросить и получить максимальное значение из функции

1

Я хотел бы сделать запрос, который получит запись с самым низким показателем, рассчитать на основе полей модели: view, unique_views и некоторый другой параметр, который является постоянным для запроса.

Мое предположение было использовать

session.query(func.min(get_metric(Post.views, Post.unique_views, 6))).first()

Но я получаю

Traceback (most recent call last):
  File "/home/john/PycharmProjects/posts/testing.py", line 32, in <module>
    session.query(func.min(get_metric(Post.views, Post.unique_views, 6))).first()
  File "/home/john/PycharmProjects/posts/testing.py", line 19, in get_metric
    metric = radians(views) + cos(unique_views) + asin(weight)
TypeError: must be real number, not InstrumentedAttribute

модель

class Post(db.Model):
    __tablename__ = 'posts'

    id = Column(Integer, primary_key=True)
    name = Column(String(20), unique=True, nullable=False)
    views = Column(Integer, nullable=False)
    unique_views = Column(Integer, nullable=False)

функция

def get_metric(views, unique_views, weight):
    metric = radians(views) + cos(unique_views) + asin(weight)
    return metric

Что мне не хватает?

Теги:
python-3.x
flask
sqlalchemy

1 ответ

0

Проблема в том, что математические функции Python работают с числами, а не с конструкциями SQLAlchemy. Чтобы создать выражение SQL, вам нужно использовать func для создания выражений функции SQL. Вы можете использовать существующую функцию, изменив ее так, чтобы она принимала пространство имен, которое она использует для математики, в качестве аргумента:

import math

def get_metric(views, unique_views, weight, math=math):
    metric = math.radians(views) + math.cos(unique_views) + math.asin(weight)
    return metric

Теперь, когда вы хотите создать SQL, передайте func как math:

session.query(func.min(get_metric(Post.views, Post.unique_views, 6, math=func))).first()
  • 1
    Обратите внимание, что это работает, потому что многие математические функции в postgresql имеют имена, которые совпадают с именами в math модуле. Некоторые функции не делают, однако: CBRT не имеют аналогов, CEILING имеет .ceil , POWER имеет .pow ... Я хотел инъекцию зависимостей , хотя, это чистый подход.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню