Мини-база для Telegram-бота: как хранить данные без SQL

Мини база данных для телеграм бота

Я сделал небольшой эксперимент и показал, как можно хранить данные пользователей телеграм-бота без Postgres или MySQL. В проекте «Помощник программиста» для этого достаточно одного users.json и пары методов Python. Такой подход идеально подходит для MVP и небольших ботов.

Почему именно JSON?

  • Быстрый старт — не нужно поднимать базы и настраивать ORM
  • Данные всегда под рукой — файл лежит рядом с кодом
  • Подходит для одного инстанса (например, на Render или Railway)
  • Хватает для учёта пользователей, статистики и простых настроек

Каркас хранилища

class UserDatabase: def __init__(self, db_file="users.json"): self.db_file = db_file self.users_data = self._load() def get_user(self, user_id: int): key = str(user_id) if key not in self.users_data: self.users_data[key] = { "user_id": user_id, "created_at": datetime.now().isoformat(), "total_questions": 0, "favorite_topics": [] } self._save() return self.users_data[key]
  • Метод get_user создаёт запись, если её нет
  • JSON сохраняется в человеко-читаемом виде (indent=2, ensure_ascii=False)
  • Ошибки загрузки/сохранения логируются, но не ломают бота

Что умеет база

  • increment_questions(user_id) — увеличивает счётчик вопросов
  • add_topic_interest(user_id, topic) — хранит интересы пользователя (до 10 последних)
  • get_active_users(days=7) — считает активных за неделю
  • Методы update_user и get_user работают как мини-ORM

Интеграция в команды

stats = user_db.get_user(user_id) text = ( f" Ваша статистика:\n\n" f"• Всего вопросов: {stats['total_questions']}\n" f"• Последняя активность: {stats['last_active']}\n" ) await update.message.reply_text(text)
  • /start — создаёт запись о пользователе
  • /stats — показывает статистику из JSON
  • /admin — доступен экспорт CSV с пользователями

Экспорт базы

async def _send_admin_export_csv(query): fieldnames = ["user_id", "username", "total_questions", "created_at", "last_active"] stream = StringIO() writer = csv.DictWriter(stream, fieldnames=fieldnames) writer.writeheader() for record in user_db.users_data.values(): writer.writerow(record) buffer = BytesIO(stream.getvalue().encode("utf-8")) buffer.seek(0) filename = f"users_export_{datetime.utcnow():%Y%m%d_%H%M%S}.csv" await query.message.reply_document( document=InputFile(buffer, filename=filename), caption="Экспорт пользователей (UTF-8)" )
  • Файл собирается в памяти через csv.DictWriter
  • Сохраняется в UTF-8, чтобы открывался в Excel/Google Sheets
  • Доступен только администратору (проверка username)

Когда JSON перестанет хватать

  • Если пользователей уже тысячи и нужно горизонтальное масштабирование
  • Если появляются требования к аудиту и отчётам
  • Если нужна отказоустойчивость

Тогда миграция на SQLite или Postgres делается безболезненно — интерфейс UserDatabase можно сохранить, заменив только реализацию.

Выводы

  • JSON идеально подходит для MVP и учебных проектов
  • Удобен в отладке, прост в поддержке
  • Даёт профили пользователей, статистику и экспорт без сложной инфраструктуры

Этот подход я использую в своём проекте «Помощник Программиста». Если нужен бот с памятью, админкой и статистикой — пишите:

Прокрутить вверх
Оставьте сообщение — отвечу через Telegram в течение 20 минут.
Отправляя данные, вы соглашаетесь с Политикой конфиденциальности