فصل ۱۱: اتصال ربات تلگرام به دیتابیس (SQL و NoSQL)

""

مقدمه فصل

فرض کن در یک ربات فروشگاهی می‌خواهی:

  • لیست محصولات رو از دیتابیس بخونی.
  • سفارشات مشتری رو ثبت کنی.
  • آخرین خرید هر کاربر رو نمایش بدی.

یا در یک ربات آموزشی:

  • نمره کاربر رو ذخیره کنی.
  • تاریخ آخرین ورود رو داشته باشی.
  • لیست سرفصل‌هایی که گذرانده رو ببینی.

برای تمام این کارها، ذخیره و خواندن داده از دیتابیس ضروریه.


بخش ۱: دیتابیس چیست؟

به زبان خیلی ساده، دیتابیس یک سیستم ذخیره اطلاعات است که به شما اجازه می‌دهد داده‌ها رو اضافه، حذف، ویرایش و جستجو کنید.

دو دسته اصلی:

نوعتوضیحمثال‌ها
SQL (بانک رابطه‌ای)داده‌ها را در جدول‌ها ذخیره می‌کند. هر جدول ستون و ردیف دارد.SQLite، MySQL، PostgreSQL
NoSQL (بدون ساختار جدولی ثابت)داده‌ها را معمولاً به‌صورت JSON یا Key-Value نگه می‌دارد.MongoDB، Redis

بخش ۲: چرا SQL یا NoSQL انتخاب کنیم؟

معیاروقتی SQL مناسب استوقتی NoSQL مناسب است
ساختار دادهثابت و دارای ستون‌های مشخصپویا و متغیر
رابطه بین داده‌هابسیار زیادکم یا بدون رابطه
مقیاس‌پذیریعمودی (تقویت سخت‌افزار)افقی (افزودن سرور)
مثال رباتفروشگاه اینترنتی با جدول سفارش‌هاربات ذخیره پیام‌های سریع یا کش

بخش ۳: نصب کتابخانه‌های لازم

برای SQL (SQLite):

pip install sqlite3  # این ماژول در پایتون به‌صورت پیش‌فرض وجود دارد

برای NoSQL (MongoDB):

pip install pymongo

بخش ۴: مثال با SQLite (SQL ساده و داخلی پایتون)

سناریو:

ساخت رباتی که:

  1. وقتی کاربر دکمه‌ای رو فشار میده، اسمش در دیتابیس ذخیره بشه.
  2. لیست تمام کاربران ذخیره‌شده قابل مشاهده باشه.

ایجاد دیتابیس و جدول

import sqlite3

# اتصال به دیتابیس یا ایجاد آن اگر وجود نداشت
conn = sqlite3.connect("bot_data.db")
cursor = conn.cursor()

# ساخت جدول کاربران
cursor.execute("""
CREATE TABLE IF NOT EXISTS users (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    user_id INTEGER UNIQUE,
    username TEXT
)
""")
conn.commit()
conn.close()

توضیح:

  • sqlite3.connect("bot_data.db") → اتصال یا ساخت فایل دیتابیس
  • CREATE TABLE IF NOT EXISTS → ساخت جدول اگر وجود نداشت
  • ستون‌ها:
  • id → یک شناسه خودکار
  • user_id → شناسه تلگرامی کاربر
  • username → نام کاربری تلگرام

اتصال این دیتابیس به ربات با دکمه Inline

from telegram import InlineKeyboardButton, InlineKeyboardMarkup, Update
from telegram.ext import ApplicationBuilder, CommandHandler, CallbackQueryHandler, ContextTypes
import sqlite3

TOKEN = "توکن_ربات"

# تابع افزودن کاربر
def add_user(user_id, username):
    conn = sqlite3.connect("bot_data.db")
    cursor = conn.cursor()
    try:
        cursor.execute("INSERT INTO users (user_id, username) VALUES (?, ?)", (user_id, username))
        conn.commit()
    except sqlite3.IntegrityError:
        pass  # کاربر قبلاً اضافه شده
    conn.close()

# تابع نمایش کاربران
def get_users():
    conn = sqlite3.connect("bot_data.db")
    cursor = conn.cursor()
    cursor.execute("SELECT user_id, username FROM users")
    data = cursor.fetchall()
    conn.close()
    return data

async def start(update: Update, context: ContextTypes.DEFAULT_TYPE):
    keyboard = [
        [InlineKeyboardButton("📥 ثبت نام", callback_data="register")],
        [InlineKeyboardButton("📋 لیست کاربران", callback_data="show_users")],
    ]
    await update.message.reply_text("یک گزینه را انتخاب کنید:", reply_markup=InlineKeyboardMarkup(keyboard))

async def button_handler(update: Update, context: ContextTypes.DEFAULT_TYPE):
    query = update.callback_query
    await query.answer()

    if query.data == "register":
        add_user(query.from_user.id, query.from_user.username or "بدون نام کاربری")
        await query.edit_message_text("✅ شما با موفقیت ثبت نام شدید.")

    elif query.data == "show_users":
        users = get_users()
        text = "👥 لیست کاربران:\n" + "\n".join([f"{u[0]} - {u[1]}" for u in users])
        await query.edit_message_text(text)

app = ApplicationBuilder().token(TOKEN).build()
app.add_handler(CommandHandler("start", start))
app.add_handler(CallbackQueryHandler(button_handler))
app.run_polling()

توضیح بخش‌به‌بخش این پروژه

  1. تابع add_user → کاربر را اگر قبلاً در دیتابیس نبوده، اضافه می‌کند.
  2. تابع get_users → لیست همه کاربران را از جدول برمی‌گرداند.
  3. دکمه «ثبت نام» → ذخیره ID و نام کاربری.
  4. دکمه «لیست کاربران» → نمایش همه کاربران.

بخش ۵: مثال با MongoDB (NoSQL)

اگر پروژه شما داده‌های دینامیک و تغییرپذیر زیادی دارد، MongoDB گزینه خوبی است.

اتصال به MongoDB:

from pymongo import MongoClient

client = MongoClient("mongodb://localhost:27017/")
db = client["telegram_bot"]
users = db["users"]

# افزودن کاربر
users.insert_one({"user_id": 12345, "username": "test_user"})

# خواندن داده
for user in users.find():
    print(user)

بخش ۶: سوالات متداول

س: آیا دیتابیس SQLite برای ربات‌های بزرگ مناسب است؟
ج: برای شروع و ربات‌های کوچک خوب است، ولی برای پروژه‌های بزرگ‌تر پیشنهاد می‌شود به MySQL یا PostgreSQL مهاجرت کنید.

س: آیا MongoDB سریع‌تر از SQL است؟
ج: برای داده‌های غیرساختاریافته و حجم خیلی بالا بله، ولی بستگی به سناریوی استفاده دارد.


بخش ۷: اشتباهات رایج

اشتباهتوضیح
عدم بستن اتصال دیتابیسباعث مصرف بیهوده منابع می‌شود.
ذخیره داده‌های غیرضروریدیتابیس باید فقط اطلاعات مهم و کاربردی نگه دارد.
نداشتن ساختار پشتیبان‌گیریدر صورت خرابی دیتابیس، اطلاعات از دست می‌رود.

بخش ۸: نکات تکمیلی

  • همیشه روی داده‌ها ایندکس بگذارید تا جستجو سریع‌تر شود.
  • از رمزنگاری برای داده‌های حساس مثل شماره تلفن استفاده کنید.
  • برای پروژه‌های واقعی، فایل تنظیمات دیتابیس رو جدا کنید و در کد اصلی نگذارید.
محمد وب‌سایت

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *