Я использую flask-sqlalchemy с python 2.7.SQLAlchemy гибридное свойство выражение datetime conversion
Я пытаюсь создать свойство, которое я могу использовать в запросе для заказа. Я уже узнал, что должен использовать hybrid_property
для этого с соответствующим выражением, но мне трудно получить объект timedelta
в выражении.
Запрос Я хочу, чтобы выполнить что-то вроде Article.query.filter(Article.language == language).order_by(Article.popularity.desc())
с
from math import exp
from datetime import datetime, timedelta
from sqlalchemy.ext.hybrid import hybrid_property
class Article(db.Model):
__tablename__ = 'articles'
article_id = db.Column(db.Integer, primary_key=True)
# ...
language = db.Column(db.String(64), default='en')
date_time = db.Column(db.DateTime, default=datetime.utcnow)
readers_frac = db.Column(db.Float, default=0.)
@hybrid_property
def popularity(self):
# compute the popularity based on the readers_frac and the time in minutes since the article was published
min_since_published = (datetime.utcnow() - self.date_time).total_seconds()/60.
popularity_decay = exp(-(min_since_published**2/(2.*1832.4**2)))
return self.readers_frac*popularity_decay
@popularity.expression
def popularity(cls):
# compute the popularity based on the readers_frac and the time in minutes since the article was published
min_since_published = (datetime.utcnow() - cls.date_time).seconds/60.
popularity_decay = exp(-(min_since_published**2/(2.*1832.4**2)))
return cls.readers_frac*popularity_decay
Однако я получаю ошибку AttributeError: Neither 'BinaryExpression' object nor 'Comparator' object has an attribute 'seconds'
при попытке вычислить min_since_published
. Любые намеки? Благодаря!!
UPDATE
Я установил ее, изменив все, чтобы sqlalchemy.func
выражений, т.е. он работает (с тузд бэкэндом) с
import sqlalchemy as sa
@popularity.expression
def popularity(cls):
# compute the popularity based on the readers_frac and the time in minutes since the article was published
min_since_published = sa.func.timestampdiff(sa.text('MINUTE'), cls.date_time, sa.func.utc_timestamp())
popularity_decay = sa.func.exp(-(sa.func.pow(min_since_published, 2)/6730009.))
return cls.readers_frac*popularity_decay
В какой базе данных вы используете? (функциональность даты и времени существенно варьируется между ними) – RazerM
Это потому, что 'datetime.utcnow() - cls.date_time' является * выражением SQL * и, следовательно, не имеет' .seconds', в отличие от 'datetime.utcnow() - self. date_time', который является 'datetime'. Вам необходимо найти соответствующую функцию в вашей РСУБД, которая даст вам эквивалентную функциональность. (То же самое с 'exp'.) – univerio
Прямо сейчас я использую SQLite в фоновом режиме, но позже это будет mysql. Я надеялся, что абстракция sqlalchemy не имеет значения ... – cod3licious