SQLAlchemy复杂查询

0 投票
1 回答
917 浏览
提问于 2025-04-18 12:01

今天我遇到了一个关于sqlalchemy查询的问题。我尝试了很久,但还是搞不清楚哪里出错了。对于sqlalchemy我还是比较新手,刚开始能处理一些中等简单的查询,但这个问题我解决不了:

units = Unit.query.join(Campaign).join(ServedUnitMetric, and_(ServedUnitMetric.client_id == clientID)).filter(
            (Campaign.active_applications.any(and_(ActiveApplication.application_id == client.application_id, ActiveApplication.enabled == True)))                    &
            (Campaign.targeting_setting.has(TargetingSetting.countries.any(and_(Country.country_code == client.locale.country_code, Country.is_active == True))))     &
            (Campaign.expiration_date > datetime.utcnow())                                                                                                            &
            (Campaign.active_campaign.has(ActiveCampaign.expenses + item.price <= Campaign.budget))                                                                   &
            (Campaign.active_campaign.has(ActiveCampaign.status == CAMPAIGN_STATUS_ACTIVE))                                                                           &
            (Campaign.max_bid >= item.price)                                                                                                                          &
            (Unit.serve_setting.has(and_(ServeSetting.language_code == client.locale.language_code, ServeSetting.valid_from <= datetime.utcnow(), ServeSetting.valid_to >= datetime.utcnow()))) &

        (
            ((Unit.serve_setting.has(ServeSetting.serve_once_per_period == True)) &  (ServedUnitMetric.unit_id != Unit.id))                                         |
            ((Unit.serve_setting.has(ServeSetting.serve_once_per_period == True)) &  (ServedUnitMetric.unit_id == Unit.id) & (datetime.utcnow() > (ServedUnitMetric.endDate + ServeSetting.period_hours)))
        )
        )

查询的第一部分是正常工作的,现在我在尝试让第二部分也正常,但我还是遇到了问题。它总是返回空数据,但我已经做了测试,确信应该返回数据。

我得到了错误信息,但仍然不知道如何解决。问题出在这里:

ServedUnitMetric.endDate + ServeSetting.period_hours

看起来sqlalchemy没有正确处理日期时间 + 时间间隔。这句话似乎被翻译成了一个双精度值。现在我需要弄清楚如何将日期时间加上时间间隔,这样就能解决问题了。我尝试使用func.adddate,但出现了溢出,我想是因为时间间隔是1970年1月1日加上你输入的间隔。

最后我找到一个看起来有效的解决方案,感谢这个链接

所以那行代码变成了:

((Unit.serve_setting.has(ServeSetting.serve_once_per_period == True)) & (ServedUnitMetric.unit_id == Unit.id) & (func.abs(func.unix_timestamp(datetime.utcnow()) - func.unix_timestamp(ServedUnitMetric.endDate)) >= (ServeSetting.period_hours * 60 * 60)))

谢谢你的帮助,

Enrico

1 个回答

0

解决办法是 func.timestamp(date)

((Unit.serve_setting.has(ServeSetting.serve_once_per_period == True)) & (ServedUnitMetric.unit_id == Unit.id) & (func.abs(func.unix_timestamp(datetime.utcnow()) - func.unix_timestamp(ServedUnitMetric.endDate)) >= (ServeSetting.period_hours * 60 * 60)))

感谢 这个链接

撰写回答