35 lines
1.2 KiB
Python
35 lines
1.2 KiB
Python
"""消息域持久化 Repository(Async)"""
|
||
|
||
from datetime import timedelta
|
||
|
||
from sqlalchemy import select
|
||
from sqlalchemy.ext.asyncio import AsyncSession
|
||
|
||
from yuxi.storage.postgres.models_business import Conversation, Message
|
||
from yuxi.utils.datetime_utils import utc_now_naive
|
||
|
||
|
||
class MessageRepository:
|
||
def __init__(self, db_session: AsyncSession):
|
||
self.db = db_session
|
||
|
||
async def get(self, message_id: int) -> Message | None:
|
||
result = await self.db.execute(select(Message).where(Message.id == message_id))
|
||
return result.scalar_one_or_none()
|
||
|
||
async def list_pending_channel_messages(self, older_than: timedelta, limit: int = 100) -> list[Message]:
|
||
cutoff = utc_now_naive() - older_than
|
||
query = (
|
||
select(Message)
|
||
.join(Conversation)
|
||
.where(
|
||
Message.delivery_status.notin_(["complete", "dead_letter", "failed"]),
|
||
Conversation.channel_type.is_not(None),
|
||
Message.created_at <= cutoff,
|
||
)
|
||
.order_by(Message.created_at.asc())
|
||
.limit(limit)
|
||
)
|
||
result = await self.db.execute(query)
|
||
return list(result.scalars().all())
|