garbage-classification / database.py
hutiger's picture
Upload folder using huggingface_hub
bf5b4d8 verified
Raw
History Blame Contribute Delete
5.38 kB
"""
AI 垃圾分类助手 - 数据库模块
使用 SQLite 记录用户分类历史和环保积分
"""
import sqlite3
from datetime import date
class Database:
def __init__(self, db_path="garbage_assistant.db"):
self.db_path = db_path
self.init_database()
def _get_conn(self):
conn = sqlite3.connect(self.db_path)
conn.row_factory = sqlite3.Row
conn.execute("PRAGMA journal_mode=WAL")
return conn
def init_database(self):
conn = self._get_conn()
conn.executescript("""
CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
username TEXT UNIQUE NOT NULL,
total_points INTEGER DEFAULT 0,
total_classifications INTEGER DEFAULT 0,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE IF NOT EXISTS records (
id INTEGER PRIMARY KEY AUTOINCREMENT,
user_id INTEGER NOT NULL,
image_path TEXT,
predicted_class TEXT NOT NULL,
confidence REAL,
points INTEGER DEFAULT 10,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES users(id)
);
CREATE TABLE IF NOT EXISTS daily_stats (
id INTEGER PRIMARY KEY AUTOINCREMENT,
user_id INTEGER NOT NULL,
date TEXT NOT NULL,
count INTEGER DEFAULT 0,
points INTEGER DEFAULT 0,
FOREIGN KEY (user_id) REFERENCES users(id),
UNIQUE(user_id, date)
);
""")
conn.commit()
conn.close()
def register_user(self, username):
conn = self._get_conn()
try:
cursor = conn.cursor()
cursor.execute("INSERT INTO users (username) VALUES (?)", (username,))
conn.commit()
user_id = cursor.lastrowid
print(f"✓ 用户 '{username}' 注册成功 (ID: {user_id})")
return user_id
except sqlite3.IntegrityError:
user_id = conn.execute(
"SELECT id FROM users WHERE username = ?", (username,)
).fetchone()["id"]
print(f"ℹ 用户 '{username}' 已存在 (ID: {user_id})")
return user_id
finally:
conn.close()
def get_user(self, username):
conn = self._get_conn()
user = conn.execute(
"SELECT * FROM users WHERE username = ?", (username,)
).fetchone()
conn.close()
return dict(user) if user else None
def add_record(self, user_id, predicted_class, confidence, image_path=None):
today = date.today().isoformat()
points = max(5, min(20, int(confidence * 20)))
conn = self._get_conn()
conn.execute(
"INSERT INTO records (user_id, image_path, predicted_class, confidence, points) VALUES (?, ?, ?, ?, ?)",
(user_id, image_path, predicted_class, confidence, points),
)
conn.execute(
"UPDATE users SET total_points = total_points + ?, total_classifications = total_classifications + 1 WHERE id = ?",
(points, user_id),
)
conn.execute(
"INSERT INTO daily_stats (user_id, date, count, points) VALUES (?, ?, 1, ?) "
"ON CONFLICT(user_id, date) DO UPDATE SET count = count + 1, points = points + ?",
(user_id, today, points, points),
)
conn.commit()
conn.close()
return points
def get_user_stats(self, user_id):
conn = self._get_conn()
user = conn.execute("SELECT * FROM users WHERE id = ?", (user_id,)).fetchone()
if not user:
conn.close()
return None
stats = dict(user)
stats["recent_records"] = [
dict(r) for r in conn.execute(
"SELECT predicted_class, confidence, points, created_at FROM records WHERE user_id = ? ORDER BY created_at DESC LIMIT 10",
(user_id,),
).fetchall()
]
stats["class_distribution"] = [
dict(r) for r in conn.execute(
"SELECT predicted_class, COUNT(*) as count FROM records WHERE user_id = ? GROUP BY predicted_class ORDER BY count DESC",
(user_id,),
).fetchall()
]
today = date.today().isoformat()
today_row = conn.execute(
"SELECT * FROM daily_stats WHERE user_id = ? AND date = ?", (user_id, today)
).fetchone()
stats["today"] = dict(today_row) if today_row else {"count": 0, "points": 0}
stats["weekly"] = [
dict(r) for r in conn.execute(
"SELECT date, count, points FROM daily_stats WHERE user_id = ? AND date >= date('now', '-7 days') ORDER BY date DESC",
(user_id,),
).fetchall()
]
conn.close()
return stats
def get_leaderboard(self, limit=10):
conn = self._get_conn()
leaders = conn.execute(
"SELECT username, total_points, total_classifications FROM users ORDER BY total_points DESC LIMIT ?",
(limit,),
).fetchall()
conn.close()
return [dict(r) for r in leaders]