Обновлен Python до версии 3.11.9 и изменены зависимости в Dockerfile и pyproject.toml. Удалены устаревшие файлы RATE_LIMITING_SOLUTION.md и тесты для rate limiting.

Обновлены пути к библиотекам в Dockerfile для соответствия новой версии Python.
Исправлены все тесты, теперь все проходят
This commit is contained in:
2026-01-25 16:07:27 +03:00
parent 5a90591564
commit d2d7c83575
21 changed files with 2324 additions and 409 deletions

View File

@@ -0,0 +1,117 @@
---
description: "Паттерны работы с базой данных, репозитории и модели"
globs: ["database/**/*.py", "**/repositories/*.py"]
---
# Паттерны работы с базой данных
## Repository Pattern
Все операции с БД выполняются через репозитории. Каждый репозиторий:
- Наследуется от `DatabaseConnection` из `database/base.py`
- Работает с одной сущностью (User, Post, Blacklist, etc.)
- Содержит методы для CRUD операций
- Использует асинхронные методы `_execute_query()` и `_execute_query_with_result()`
### Структура репозитория
```python
from database.base import DatabaseConnection
from database.models import User
class UserRepository(DatabaseConnection):
"""Репозиторий для работы с пользователями."""
async def create_tables(self):
"""Создание таблицы пользователей."""
query = '''
CREATE TABLE IF NOT EXISTS our_users (
user_id INTEGER NOT NULL PRIMARY KEY,
...
)
'''
await self._execute_query(query)
self.logger.info("Таблица пользователей создана")
async def add_user(self, user: User) -> None:
"""Добавление нового пользователя."""
query = "INSERT OR IGNORE INTO our_users (...) VALUES (...)"
params = (...)
await self._execute_query(query, params)
self.logger.info(f"Пользователь добавлен: {user.user_id}")
async def get_user_by_id(self, user_id: int) -> Optional[User]:
"""Получение пользователя по ID."""
query = "SELECT * FROM our_users WHERE user_id = ?"
rows = await self._execute_query_with_result(query, (user_id,))
# Преобразование row в модель User
...
```
## Модели данных
- Модели определены в `database/models.py`
- Используются dataclasses или простые классы
- Модели передаются между слоями (Repository → Service → Handler)
## Работа с БД
### AsyncBotDB
- Основной интерфейс для работы с БД
- Использует `RepositoryFactory` для доступа к репозиториям
- Методы делегируют вызовы соответствующим репозиториям
### DatabaseConnection
- Базовый класс для всех репозиториев
- Предоставляет методы:
- `_get_connection()` - получение соединения
- `_execute_query()` - выполнение запроса без результата
- `_execute_query_with_result()` - выполнение запроса с результатом
- Автоматически управляет соединениями (открытие/закрытие)
- Настраивает PRAGMA для оптимизации SQLite
### Важные правила
1. **Всегда используйте параметризованные запросы** для защиты от SQL injection:
```python
# ✅ Правильно
query = "SELECT * FROM users WHERE user_id = ?"
await self._execute_query_with_result(query, (user_id,))
# ❌ Неправильно
query = f"SELECT * FROM users WHERE user_id = {user_id}"
```
2. **Логируйте важные операции**:
```python
self.logger.info(f"Пользователь добавлен: {user_id}")
self.logger.error(f"Ошибка при добавлении пользователя: {e}")
```
3. **Используйте транзакции** для множественных операций (если нужно):
```python
async with await self._get_connection() as conn:
await conn.execute(...)
await conn.execute(...)
await conn.commit()
```
4. **Обрабатывайте None** при получении данных:
```python
rows = await self._execute_query_with_result(query, params)
if not rows:
return None
row = rows[0]
```
## RepositoryFactory
- Создает и кэширует экземпляры репозиториев
- Доступ через свойства: `factory.users`, `factory.posts`, etc.
- Используется в `AsyncBotDB` для доступа к репозиториям
## Миграции
- SQL миграции в `database/schema.sql`
- Python скрипты для миграций в `scripts/`
- Всегда проверяйте существование таблиц перед созданием: `CREATE TABLE IF NOT EXISTS`