#python #sql #sqlalchemy
#python #sql #sqlalchemy
Вопрос:
Как я уже упоминал в своем ответе, это неправильный подход.
Мое заявление:
db.session.query(
m.SiteServicePrice, func.max(m.SiteServicePrice.created).label('latest')).filter(
m.SiteServicePrice.site_id == 2001).group_by(m.SiteServicePrice.service_id).all()
Я хотел бы получить список объектов m.SiteServicePrice, а не список кортежей.
Это:
[<SiteServicePrice(site_id:2001 service_id:12 created:2019-01-30 03:25:31)>,
<SiteServicePrice(site_id:2001 service_id:21 created:2019-01-30 03:25:31)>,
<SiteServicePrice(site_id:2001 service_id:37 created:2019-01-30 03:25:31)>]
вместо этого:
[(<SiteServicePrice(site_id:2001 service_id:12 created:2019-01-30 03:25:31)>, datetime.datetime(2020, 5, 28, 22, 31, 35)),
(<SiteServicePrice(site_id:2001 service_id:21 created:2019-01-30 03:25:31)>, datetime.datetime(2020, 5, 28, 22, 31, 54)),
(<SiteServicePrice(site_id:2001 service_id:37 created:2019-01-30 03:25:31)>, datetime.datetime(2020, 5, 28, 22, 32, 15)))]
Есть ли способ сохранить func.max(m.SiteServicePrice.created)
как часть запроса и указать SQLAlchemy не включать его в результат?
Я знаю, что могу извлечь объекты m.SiteServicePrice из результата, используя понимание списка или другими способами, но мне любопытно, есть ли способ сделать это с помощью SQLAlchemy.
Ответ №1:
Оказывается, мой исходный SQL-запрос и оператор SQLAlchemy были неверными.
Исходный sql-запрос:
select
max(created),
created,
service_id, c_price, s_price
from
site_service_prices
where
site_id = 2001
group by service_id;
Здесь я не включаю все ключи из select
in group by
. MySQL и MariaDB не рассматривают это как ошибку, каковой она и является. Объяснение из базы знаний MariaDB
Для получения списка latest
элементов из запроса с использованием max(date_field) требуется подзапрос.
это правильный запрос:
1 SELECT
2 id, site_id, service_id, created
3 FROM
4 site_service_prices join(
5 SELECT
6 site_id, service_id, max(created) AS created
7 FROM
8 site_service_prices
9 WHERE
10 site_id = 1
11 GROUP BY
12 site_id, service_id
13 ) t2
14 USING (
15 site_id, service_id, created
16 );
и это то, как должен выглядеть запрос SQLAlchemy:
# create a subquery with IDs and max date
sq = db.session.query(
m.SiteServicePrice.service_id.label('service_id'),
func.max(m.SiteServicePrice.created).label('created')).filter(
m.SiteServicePrice.site_id == 1).group_by(
m.SiteServicePrice.service_id).subquery()
# join with subquery
db.session.query(m.SiteServicePrice).join(sq,
and_(m.SiteServicePrice.service_id == sq.c.service_id,
m.SiteServicePrice.created == sq.c.created)).filter(
m.SiteServicePrice.site_id == 1).order_by(
m.SiteServicePrice.created.desc()).all()
Ответ №2:
Просто повторите их с помощью простого цикла for и сохраните в другом массиве.
Комментарии:
1. Я знаю, что могу это сделать. Я даже упомянул об этом в конце своего вопроса. Я хотел бы знать, есть ли способ sqlalchemy делать то, что я хочу.