Я новичок в Python и разрабатываю бота для Telegram. Мне нужно извлекать определенные строки из базы данных, если будут найдены соответствия. Как правильно это реализовать? Я не смог найти нужную информацию в интернете. Вот что я уже попробовал сделать: <br/> <br/> <pre><code class="python">@start_router.message(Form.searсh_for_name)
async def search_name(message: types.Message):
message_name = message.text.strip()
async with aiosqlite.connect('base.db') as db:
await db.execute('SELECT username, user_tg, name, soname FROM user WHERE [name] = "message_name"')
users = db.fetchall()
users_str = "\n".join([str(user) for user in users])
await message.answer(users_str)
await db.commit()</code></pre> <br/> <br/> Но у меня возникает ошибка: AttributeError: 'Connection' object has no attribute 'fetchall'. Я понимаю причину ошибки, но мне кажется, что основной подход неверен. Не могли бы вы помочь?
Конечно! Я помогу вам исправить ваш код для извлечения данных из базы данных SQLite с использованием `aiogram`.
Сначала давайте взглянем на основные моменты в вашем коде. Ошибка `AttributeError: 'Connection' object has no attribute 'fetchall'` происходит, потому что вы пытаетесь вызвать метод `fetchall` на объекте соединения, в то время как необходимым действием для получения данных является использование курсора.
Вот правильный подход:
1. Создайте курсор для выполнения SQL-запроса.
2. Воспользуйтесь методом `fetchall()` на курсоре, а не на соединении.
Также ваш SQL-запрос содержит ошибку в подстановке параметров. Вы должны использовать параметризированные запросы, чтобы избежать SQL-инъекций.
Вот исправленный пример вашего кода:
```python
from aiogram import types
from aiogram.dispatcher import F
from aiosqlite import connect
@start_router.message(Form.searсh_for_name)
async def search_name(message: types.Message):
message_name = message.text.strip()
async with connect('base.db') as db:
async with db.execute('SELECT username, user_tg, name, soname FROM user WHERE name = ?', (message_name,)) as cursor:
users = await cursor.fetchall()
if users: # Проверяем, если есть результаты
users_str = "\n".join([f"Username: {user[0]}, TG: {user[1]}, Name: {user[2]}, Surname: {user[3]}" for user in users])
else:
users_str = "Пользователи не найдены."
await message.answer(users_str)
```
### Разбор изменений:
1. **Параметризированный запрос**: Теперь в SQL-запросе используется `?` для подстановки значения `message_name`. Это защищает от SQL-инъекций.
2. **Использование курсора**: Мы использовали `async with db.execute(...) as cursor`, чтобы создать курсор для выполнения запроса. Затем вызвали `await cursor.fetchall()` для получения всех строк результата.
3. **Проверка результатов**: Проверяем, получили ли мы пользователей из базы данных. Если нет, отправляем сообщение об этом.
4. **Форматирование вывода**: Для лучшего представления информации, мы отформатировали вывод, чтобы сделать его более читабельным.
Обязательно проверьте, чтобы библиотека `aiosqlite` была установлена. Если она еще не установлена, вы можете сделать это с помощью `pip`:
```bash
pip install aiosqlite
```
Теперь ваш бот должен корректно извлекать данные из базы данных SQLite!
Сначала создай курсор , потом на нём уже вызывай execute() для выполнения запросов. Когда закончишь работать с курсором - вызови close() . Это часть спецификации DB-API 2.0, которому следует большинство библиотек для работы с БД на питоне.
Если у тебя эта же ошибка возникает и без телеграма, то упоминание телеграма можно полностью убрать из вопроса.
Проблема у тебя только с тем, что ты не читал документацию от aiosqlite и пытаешься с ним работать как с синхронным sqlite.
https://aiosqlite.omnilib.dev/en/stable/api.html#c...
У Connection действительно нет метода fetchall.
Нужно использовать метод execute_fetchall.
Либо используй курсоры, что предпочтительней.
PS: у многих новичков возникают трудности, когда они сразу пытаются делать большой проект, где сочетаются разные фреймворки/библиотеки/технологии. Пока ты не освоился с языком и не научился ориентироваться в документации - лучше попробуй с чего-то более простого.
Например, если хочешь поработать с телегой - сделай сначала хранение данных полностью в оперативной памяти на списках и словарях.
Если хочешь поработать с sqlite - попробуй в качестве интерфейса пользователя использовать консоль