@Hgds

Почему возникает ошибка TypeError: 'Item' object is not iterable?

Я пишу бота на aiogram и мне нужно чтобы из БД кнопками Inline выводились товары, но появляется ошибка:
TypeError: 'Item' object is not iterable

При этом, когда из БД выводятся категории – то всё нормально.

И ещё ругается на line 24 в handlers.py:
handlers.py
from aiogram import F, Router
from aiogram.filters import CommandStart, Command
from aiogram.types import Message, CallbackQuery
from aiogram.fsm.state import State, StatesGroup
from aiogram.fsm.context import FSMContext

import app.keyboards as kb
import app.database.requests as rq

router = Router()

@router.message(CommandStart())
async def cmd_start(message: Message):
    await rq.set_user(message.from_user.id)
    await message.answer_photo(photo='https://ltdfoto.ru/images/2024/05/12/KARTINKI-DLY-BOTA-VSYKOE3.jpg',
                               caption=f'Привет {message.from_user.first_name}, ты готов к выгодным предложениям?\n \nЕсли да, то кликай на кнопки ниже!',
                               reply_markup=await kb.categories())
    

@router.callback_query(F.data.startswith('category_'))
async def category(callback: CallbackQuery):
    await callback.answer('Вы выбрали категорию')
    await callback.message.answer('Выберите товар по категории', 
                                  reply_markup=await kb.items(callback.data.split('_')[1]))


keyboards.py
from aiogram.types import (InlineKeyboardMarkup, InlineKeyboardButton,
                           ReplyKeyboardMarkup, KeyboardButton)

from aiogram.utils.keyboard import InlineKeyboardBuilder

from app.database.requests import get_categories, get_category_item


async def categories():
    all_categories = await get_categories()
    keyboard = InlineKeyboardBuilder()
    for category in all_categories:
        keyboard.add(InlineKeyboardButton(text=category.name, callback_data=f"category_{category.id}"))
    return keyboard.adjust(2).as_markup()


async def items(category_id):
    all_items = await get_category_item(category_id)
    keyboard = InlineKeyboardBuilder()
    for item in all_items:
        keyboard.add(InlineKeyboardButton(text=item.name, callback_data=f"item_{item.id}"))
    keyboard.add(InlineKeyboardButton(text='На главную', callback_data=f'to_main'))
    return keyboard.adjust(2).as_markup()


models.py
from sqlalchemy import BigInteger, String, ForeignKey
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column
from sqlalchemy.ext.asyncio import AsyncAttrs, async_sessionmaker, create_async_engine

engine = create_async_engine(url='sqlite+aiosqlite:///db.sqlite3')

async_session = async_sessionmaker(engine)

class Base(AsyncAttrs, DeclarativeBase):
    pass

class User(Base):
    __tablename__ = 'users'
    
    id: Mapped[int] = mapped_column(primary_key=True)
    tg_id = mapped_column(BigInteger)


class Category(Base):
    __tablename__ = 'categories'
    
    id: Mapped[int] = mapped_column(primary_key=True)
    name: Mapped[str] = mapped_column(String(25))


class Item(Base):
    __tablename__ = 'items'
    
    id: Mapped[int] = mapped_column(primary_key=True)
    name: Mapped[str] = mapped_column(String(25))
    description: Mapped[str] = mapped_column(String(300))
    category: Mapped[int] = mapped_column(ForeignKey('categories.id'))
    photo: Mapped[str] = mapped_column(String(120))


async def async_main():
    async with engine.begin() as conn:
        await conn.run_sync(Base.metadata.create_all)


requests.py
from app.database.models import async_session
from app.database.models import User, Category, Item
from sqlalchemy import select, update, delete


async def set_user(tg_id: int) -> None:
    async with async_session() as session:
        user = await session.scalar(select(User).where(User.tg_id == tg_id))

        
            
        if not user:
            session.add(User(tg_id=tg_id))
            await session.commit()
            

async def get_categories():
    async with async_session() as session:
        return await session.scalars(select(Category))
    

async def get_category_item(category_id):
    async with async_session() as session:
        return await session.scalar(select(Item).where(Item.category == category_id))


Код ошибки
INFO:aiogram.event:Update id=81400064 is not handled. Duration 108 ms by bot id=6871204270
ERROR:aiogram.event:Cause exception while process update id=81400064 by bot id=6871204270
TypeError: 'Item' object is not iterable
Traceback (most recent call last):
  File "D:\Bot Vsyakoye\venv\Lib\site-packages\aiogram\dispatcher\dispatcher.py", line 309, in _process_update
    response = await self.feed_update(bot, update, **kwargs)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "D:\Bot Vsyakoye\venv\Lib\site-packages\aiogram\dispatcher\dispatcher.py", line 158, in feed_update
    response = await self.update.wrap_outer_middleware(
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "D:\Bot Vsyakoye\venv\Lib\site-packages\aiogram\dispatcher\middlewares\error.py", line 25, in __call__
    return await handler(event, data)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "D:\Bot Vsyakoye\venv\Lib\site-packages\aiogram\dispatcher\middlewares\user_context.py", line 49, in __call__
    return await handler(event, data)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "D:\Bot Vsyakoye\venv\Lib\site-packages\aiogram\fsm\middleware.py", line 42, in __call__
    return await handler(event, data)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "D:\Bot Vsyakoye\venv\Lib\site-packages\aiogram\dispatcher\event\telegram.py", line 121, in trigger
    return await wrapped_inner(event, kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "D:\Bot Vsyakoye\venv\Lib\site-packages\aiogram\dispatcher\event\handler.py", line 43, in call
    return await wrapped()
           ^^^^^^^^^^^^^^^
  File "D:\Bot Vsyakoye\venv\Lib\site-packages\aiogram\dispatcher\dispatcher.py", line 276, in _listen_update
    return await self.propagate_event(update_type=update_type, event=event, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "D:\Bot Vsyakoye\venv\Lib\site-packages\aiogram\dispatcher\router.py", line 142, in propagate_event
    return await observer.wrap_outer_middleware(_wrapped, event=event, data=kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "D:\Bot Vsyakoye\venv\Lib\site-packages\aiogram\dispatcher\router.py", line 137, in _wrapped
    return await self._propagate_event(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "D:\Bot Vsyakoye\venv\Lib\site-packages\aiogram\dispatcher\router.py", line 170, in _propagate_event
    response = await router.propagate_event(update_type=update_type, event=event, **kwargs)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "D:\Bot Vsyakoye\venv\Lib\site-packages\aiogram\dispatcher\router.py", line 142, in propagate_event
    return await observer.wrap_outer_middleware(_wrapped, event=event, data=kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "D:\Bot Vsyakoye\venv\Lib\site-packages\aiogram\dispatcher\router.py", line 137, in _wrapped
    return await self._propagate_event(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "D:\Bot Vsyakoye\venv\Lib\site-packages\aiogram\dispatcher\router.py", line 162, in _propagate_event
    response = await observer.trigger(event, **kwargs)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "D:\Bot Vsyakoye\venv\Lib\site-packages\aiogram\dispatcher\event\telegram.py", line 121, in trigger
    return await wrapped_inner(event, kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "D:\Bot Vsyakoye\venv\Lib\site-packages\aiogram\dispatcher\event\handler.py", line 43, in call
    return await wrapped()
           ^^^^^^^^^^^^^^^
  File "D:\Bot Vsyakoye\app\handlers.py", line 24, in category
    reply_markup=await kb.items(callback.data.split('_')[1]))
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "D:\Bot Vsyakoye\app\keyboards.py", line 20, in items
    for item in all_items:
TypeError: 'Item' object is not iterable


P.S. Я новичок в этом, поэтому если увидите ещё какие-то недочёты в коде, то пишите, открыт к конструктивной критике.
  • Вопрос задан
  • 123 просмотра
Решения вопроса 1
Vindicar
@Vindicar
RTFM!
У тебя get_category_item() возвращает только один предмет из категории, а ты думаешь, что она возвращает коллекцию предметов. Хотя ты сам делаешь scalar.
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы