Quantcast
Channel: Active questions tagged python - Stack Overflow
Viewing all articles
Browse latest Browse all 13921

Optimize multiple SQLAlchemy queries to one query

$
0
0

I am trying to write a function for a given user to return a count of all online users and offline users for each chatroom the given user is a part of.

The methods listed below achieve what I want but it writes multiple queries to postgres and I want to be able to do it in one query.

class Users(Base):    id: Mapped[uuid:UUID] = mapped_column(        UUID(as_uuid=True), unique=True, default=uuid.uuid4, autoincrement=True    )    username: Mapped[str] = mapped_column(String, primary_key=True, unique=True)    password: Mapped[str] = mapped_column(String, nullable=False)    created_at: Mapped[datetime] = mapped_column(        DateTime, nullable=False, default=datetime.now    )    sessions: Mapped[List["Sessions"]] = relationship(        back_populates="user", lazy="selectin"    )    messages: Mapped[List["Messages"]] = relationship(        back_populates="user", lazy="selectin"    )    created_chatrooms: Mapped[List["Chatrooms"]] = relationship(        back_populates="created_by", lazy="selectin"    )    chatrooms: Mapped[List["Chatrooms"]] = relationship(        secondary=user_chatroom_table, back_populates="users"    )    online: Mapped[bool] = mapped_column(Boolean, nullable=False, default=False)    async def get_chatrooms_and_user_counts(self, db: AsyncSession):        chatroom_ids = await self.get_user_chatrooms(db=db)        chatrooms_info = []        for chatroom_id in chatroom_ids:            online_count_stmt = (                select(func.count())                .select_from(                    user_chatroom_table.join(                        Users, user_chatroom_table.c.user_id == Users.id                    )                )                .where(                    user_chatroom_table.c.chatroom_id == chatroom_id,                    Users.online == True,                )            )            offline_count_stmt = (                select(func.count())                .select_from(                    user_chatroom_table.join(                        Users, user_chatroom_table.c.user_id == Users.id                    )                )                .where(                    user_chatroom_table.c.chatroom_id == chatroom_id,                    Users.online == False,                )            )            online_count_result = await db.execute(online_count_stmt)            offline_count_result = await db.execute(offline_count_stmt)            online_count = online_count_result.scalar()            offline_count = offline_count_result.scalar()            chatrooms_info.append(                {"chatroom_id": str(chatroom_id),"online": online_count,"offline": offline_count,                }            )        return chatrooms_info    async def get_user_chatrooms(self, db: AsyncSession) -> List["Chatrooms"]:"""        Asynchronously get a list of chatrooms that the given user is a part of.        :param user_id: UUID of the user to check.        :param db: SQLAlchemy AsyncSession.        :return: List of Chatrooms the user is a part of."""        # Create a query that selects chatrooms joined by the given user_id        stmt = (            select(Chatrooms.id)            .join(                user_chatroom_table, Chatrooms.id == user_chatroom_table.c.chatroom_id            )            .where(user_chatroom_table.c.user_id == self.id)        )        result = await db.execute(stmt)        chatrooms = result.scalars().all()        return chatroomsclass Chatrooms(Base):    id: Mapped[uuid:UUID] = mapped_column(        UUID(as_uuid=True),        primary_key=True,        unique=True,        default=uuid.uuid4,    )    name: Mapped[str] = mapped_column(unique=True, nullable=False)    created_by: Mapped["Users"] = relationship(        back_populates="created_chatrooms", lazy="selectin"    )    user_id: Mapped[uuid:UUID] = mapped_column(        UUID(as_uuid=True), ForeignKey("users.id")    )    created_at: Mapped[datetime] = mapped_column(        DateTime, nullable=False, default=datetime.now    )    category: Mapped[str] = mapped_column(nullable=False)    messages: Mapped[List["Messages"]] = relationship(        back_populates="chatroom", lazy="selectin"    )    users: Mapped[List[Users]] = relationship(        secondary=user_chatroom_table, back_populates="chatrooms"    )

Viewing all articles
Browse latest Browse all 13921

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>