Почему один и тот же запрос в postgresql и sqlalchemy выдают разные результаты?
Столкнулся с проблемой при выполнении запроса на прямую в postgresql возвращается следующий результат:

Но если этот же запрос выполнить через sqlalchemy:
expression = """
SELECT C.*, m2.text
FROM client c
JOIN (
SELECT user_id, MAX(complaint_date) AS latest_timestamp
FROM message_to_web
GROUP BY user_id
) m ON c.client_id = m.user_id
JOIN message_to_web m2 ON m.user_id = m2.user_id AND m.latest_timestamp = m2.complaint_date;
"""
result = await session.execute(text(expression))
user_list = result.scalars().all()
Получаю просто список id:
[
100000300,
100000360,
6373403021,
100000485
]
В чем может быть проблема?
вот код моделей:
class MessageToWeb(Base):
"""Таблица сообщений между пользователем и менеджером
Атрибуты:
- message_id (int): id сообщения
- user_id (ind): id пользователя
- master_id (ind): id мастера
- text (str): Текст сообщения
- destination (str): Адресат сообщения. Если сообщение от клиента менеджеру - meneger, отк менеджера клиенту - client
"""
__tablename__ = "message_to_web"
message_id = Column(BigInteger, primary_key=True, autoincrement=True)
user_id = Column(BigInteger, ForeignKey("client.client_id"), autoincrement=False, nullable=False)
master_id = Column(BigInteger, ForeignKey("master.master_id"), autoincrement=False, nullable=False)
text = Column(String(1200), nullable=False)
destination = Column(String(400), nullable=False)
complaint_date = Column(DateTime, nullable=False, server_default=func.now())
# Модели бота
class Client(Base):
"""
Таблица с информацией о клиенте.
Атрибуты:
- client_id (int): ID клиента в Telegram.
- username (str): Логин клиента в Telegram.
- client_url (str): Ссылка на клиента в Telegram.
- name (str): Имя клиента.
- city (str): Город клиента.
- tattoo_type (str): Тип татуировки клиента (цветная/одноцветная/оба варианта).
- is_advertising_allowed (bool): Флаг, указывающий, согласен ли пользователь получать
рекламные сообщения. True - согласен, False - не согласен.
- is_model (bool): Флаг, указывающий, согласен ли пользователь быть моделью
(делать тату по себестоимости). True - согласен, False - не согласен.
- is_bot_usage_consent (bool): Флаг, указывающий согласен ли пользователь использовать бота.
True - согласен, False - не согласен.
- is_blocked (bool): Флаг, указывающий, заблокирован ли пользователь в боте.
True - заблокирован, False - не заблокирован.
"""
__tablename__ = "client"
client_id = Column(BigInteger, primary_key=True, autoincrement=False)
username = Column(String(60), nullable=True)
client_url = Column(String(130), nullable=False)
name = Column(String(130), nullable=False)
city = Column(String(70), nullable=False)
tattoo_type = Column(String(60), nullable=False)
date_of_reg = Column(DateTime, nullable=False, server_default=func.now())
is_advertising_allowed = Column(Boolean, default=True, nullable=False)
is_model = Column(Boolean, default=False, nullable=False)
is_bot_usage_consent = Column(Boolean, default=False, nullable=False)
is_blocked = Column(Boolean, default=False, nullable=False)
complaints = relationship(
"Complaints", back_populates="client", cascade="delete, delete-orphan"
)
likes = relationship(
"Likes", back_populates="client", cascade="delete, delete-orphan"
)
contact_requests = relationship(
"ContactRequests", back_populates="client", cascade="delete, delete-orphan"
)
styles = relationship(
"ClientStyles", back_populates="client", cascade="delete, delete-orphan"
)
messages = relationship(
"MessageToWeb", backref="client", cascade="delete, delete-orphan",
)
Ответы (1 шт):
Автор решения: Nebob
→ Ссылка
Разобрался. Проблема заключалась в функции scalars(). Она возвращает только первые элементы списка, получаемого от запроса.