gpt4 book ai didi

python - 使用 Hybrid_property 对从其他列的值派生的时间列进行排序

转载 作者:行者123 更新时间:2023-12-01 07:00:39 28 4
gpt4 key购买 nike

我正在尝试构建一个事件预订系统作为学习 Python 和 Web 开发的副项目。以下是我的项目中实现的两个模型。 EventSlot 表示为特定事件安排的时间段。

模型

from app import db
from sqlalchemy import ForeignKey
from dateutil.parser import parse
from datetime import timedelta
from sqlalchemy.ext.hybrid import hybrid_property


class Event(db.Model):
event_id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String, index=True, nullable=False)
duration = db.Column(db.Float, nullable=False)
price = db.Column(db.Float, nullable=False)

slots = db.relationship('EventSlot', cascade='all, delete', back_populates='event')


class EventSlot(db.Model):
slot_id = db.Column(db.Integer, primary_key=True)
event_date = db.Column(db.DateTime, nullable=False)
event_id = db.Column(db.Integer, ForeignKey('event.event_id'))

event = db.relationship('Event', back_populates='slots')

我为管理员用户提供了一个管理页面(Flask-Admin)来查看数据库记录。在 EventSlot 页面上,我添加了“开始时间”和“结束时间”列,我希望将其进行排序。我已将以下内容附加到 EventSlot 模型中:

class EventSlot(db.Model):
#...

## working as intended ##
@hybrid_property
def start_time(self):
dt = parse(str(self.event_date))
return dt.time().strftime('%I:%M %p')

@start_time.expression
def start_time(cls):
return db.func.time(cls.event_date)


## DOES NOT WORK: can display derived time, but sorting is incorrect ##
@hybrid_property
def end_time(self):
rec = Event.query.filter(Event.event_id == self.event_id).first()
duration = rec.duration * 60
derived_time = self.event_date + timedelta(minutes=duration)
dt = parse(str(derived_time))
return dt.time().strftime('%I:%M %p')

@end_time.expression
def end_time(cls):
rec = Event.query.filter(Event.event_id == cls.event_id).first()
duration = '+' + str(int(rec.duration * 60)) + ' minutes'
return db.func.time(cls.event_date, duration)

从下图中可以看出,当我按“结束时间”排序时,排序顺序是错误的。似乎仍在按开始时间排序。这里可能有什么问题?

(诚然,我还是不明白hybrid_properties。我以为start_time工作时我已经明白了,但现在看来我还是不明白......)

sorting results

最佳答案

end_time 的表达式中,cls.event_id 表示列,而不是值,因此查询最终会在 Event 之间执行隐式联接code> 和 EventSlot 并选择该连接的第一个结果。这当然不是您想要的,但对于 EventSlot,您希望在 SQL 中找出相关 Event 的持续时间。这似乎是使用相关标量子查询的好地方:

@end_time.expression
def end_time(cls):
# Get the duration of the related Event
ev_duration = Event.query.\
with_entities(Event.duration * 60).\
filter(Event.event_id == cls.event_id).\
as_scalar()
# This will form a string concatenation SQL expression, binding the strings as
# parameters to the query.
duration = '+' + ev_duration.cast(db.String) + ' minutes'
return db.func.time(cls.event_date, duration)

请注意,当在查询上下文中访问属性时,查询不会运行,而是成为父查询的一部分。

关于python - 使用 Hybrid_property 对从其他列的值派生的时间列进行排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58643501/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com