6.8 KiB
Implementing SQLite Database in Telegram Scheduler Bot
This document explains how to enhance your existing Telegram Scheduler Bot (telegram_scheduler_v2.py) to include SQLite database functionality, resulting in telegram_scheduler_v3.py.
Overview
The transition from telegram_scheduler_v2.py to telegram_scheduler_v3.py introduces persistent storage capabilities using SQLite, allowing the bot to store, retrieve, and manage schedule data beyond runtime.
What is SQLite?
SQLite is a lightweight, serverless, self-contained SQL database engine. It stores the entire database in a single file, making it ideal for applications that need local data persistence without setting up a separate database server.
How the Database File (schedule.db) Appears
The schedule.db file is automatically created when:
- The bot runs for the first time after implementing SQLite functionality
- The
init_db()function executes, which creates the database file if it doesn't exist - The first database operation occurs (like adding a record)
The file appears in the same directory as your Python script and persists between program runs.
Step-by-Step Implementation Guide
1. Import Required Libraries
Add SQLite3 import to your existing imports:
import sqlite3
2. Database Initialization Function
Create a function to initialize your database:
def init_db():
"""Initialize the SQLite database and create tables if they don't exist."""
conn = sqlite3.connect(DATABASE_NAME)
cursor = conn.cursor()
# Create table for schedule entries
cursor.execute('''
CREATE TABLE IF NOT EXISTS schedule (
id INTEGER PRIMARY KEY AUTOINCREMENT,
day TEXT NOT NULL,
period INTEGER NOT NULL,
subject TEXT NOT NULL,
class_name TEXT NOT NULL,
room TEXT NOT NULL,
UNIQUE(day, period)
)
''')
conn.commit()
conn.close()
3. Database Connection Setup
Define the database name and initialize it:
# Database setup
DATABASE_NAME = "schedule.db"
# Initialize the database
init_db()
4. Data Manipulation Functions
Add functions to interact with the database:
def add_schedule_entry(day, period, subject, class_name, room):
"""Add a new schedule entry to the database."""
conn = sqlite3.connect(DATABASE_NAME)
cursor = conn.cursor()
try:
cursor.execute('''
INSERT OR REPLACE INTO schedule (day, period, subject, class_name, room)
VALUES (?, ?, ?, ?, ?)
''', (day, period, subject, class_name, room))
conn.commit()
conn.close()
return True
except sqlite3.Error as e:
print(f"Database error: {e}")
conn.close()
return False
def load_schedule_from_db():
"""Load schedule from the SQLite database."""
conn = sqlite3.connect(DATABASE_NAME)
cursor = conn.cursor()
cursor.execute("SELECT day, period, subject, class_name, room FROM schedule ORDER BY day, period")
rows = cursor.fetchall()
conn.close()
# Group by day
schedule = {}
for day, period, subject, class_name, room in rows:
if day not in schedule:
schedule[day] = []
class_info = f"Subject: {subject} Class: {class_name} Room: {room}"
schedule[day].append((str(period), class_info))
return schedule
5. Update Existing Functions to Use Database
Modify your schedule-retrieving functions to use the database instead of CSV:
async def where_am_i(update: Update, context: ContextTypes.DEFAULT_TYPE):
"""Tell user where they should be right now."""
# Reload schedule from DB to ensure latest data
schedule = load_schedule_from_db()
# ... rest of function remains similar but uses 'schedule' from DB
6. Add Conversation State Management
To handle multi-step interactions like the /add command:
# User states for tracking conversations
user_states = {} # Stores user conversation state
7. Implement the New /add Command
Create an interactive command that collects data from the user:
async def add(update: Update, context: ContextTypes.DEFAULT_TYPE):
"""Start the process of adding a new schedule entry."""
user_id = update.effective_user.id
user_states[user_id] = {"step": "waiting_day"}
await update.message.reply_text(
"📅 Adding a new class to the schedule.\n"
"Please enter the day of the week (e.g., Monday, Tuesday, etc.):"
)
8. Handle Messages During Conversations
Add a general message handler for interactive flows:
async def handle_message(update: Update, context: ContextTypes.DEFAULT_TYPE):
"""Handle user messages during the add process."""
# Implementation for processing user input during multi-step conversations
# Handles day -> period -> subject -> class -> room sequence
9. Register New Handlers
Add the new handlers to your main function:
def main():
# Create the Application
application = Application.builder().token(BOT_TOKEN).build()
# Add command handlers
application.add_handler(CommandHandler("start", start))
application.add_handler(CommandHandler("whereami", where_am_i))
application.add_handler(CommandHandler("schedule", schedule))
application.add_handler(CommandHandler("tomorrow", tomorrow))
application.add_handler(CommandHandler("add", add)) # New command
application.add_handler(CommandHandler("help", help_command))
# Add message handler for conversation flow
application.add_handler(MessageHandler(filters.TEXT & ~filters.COMMAND, handle_message))
Key Changes Summary
| Aspect | telegram_scheduler_v2.py | telegram_scheduler_v3.py |
|---|---|---|
| Data Storage | CSV file | SQLite database |
| Persistence | Lost when program ends | Persists between runs |
| New Classes | Cannot add dynamically | Interactive /add command |
| Data Updates | Requires manual CSV editing | Real-time updates via bot |
Benefits of Using SQLite
- Persistence: Data survives bot restarts
- Dynamic Updates: Users can add new classes without changing files
- Data Integrity: Built-in constraints prevent duplicates
- Scalability: Easy to extend with additional tables/fields
- Performance: Fast queries for schedule lookups
Security Note
The schedule.db file contains your schedule data and should be protected accordingly. In production environments, consider access controls and backups.
Troubleshooting
- If the database isn't being created, ensure your application has write permissions in the directory
- Check logs for SQLite error messages if operations fail
- The database file will grow as more entries are added over time