You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

卡路里追踪应用数据存储优化:解决删除操作难题

卡路里追踪应用的食物数据存储优化方案

针对你当前纯文本存储删改繁琐、JSON操作不便、shelve效率低的问题,推荐两种实用的优化方案:


方案一:使用SQLite本地数据库(推荐)

SQLite是Python内置的轻量级关系型数据库,无需额外安装依赖,支持精准的增删改查操作,适合结构化数据管理。

1. 初始化数据库

先创建存储食物数据的表,程序启动时执行一次即可:

import sqlite3

def init_db():
    conn = sqlite3.connect('food_tracker.db')
    cursor = conn.cursor()
    # 创建带自增ID的食物表,ID作为唯一标识方便删改
    cursor.execute('''CREATE TABLE IF NOT EXISTS foods
                 (id INTEGER PRIMARY KEY AUTOINCREMENT,
                  name TEXT NOT NULL,
                  calories INTEGER NOT NULL,
                  protein INTEGER NOT NULL,
                  fat INTEGER NOT NULL,
                  carbs INTEGER NOT NULL)''')
    conn.commit()
    conn.close()

# 程序启动时初始化数据库
init_db()

2. 修改saveFood函数适配数据库存储

def saveFood():
    # 输入食物名称
    foodName = input('Enter food name\n').strip().upper()
    
    # 输入并验证数值型字段(卡路里、蛋白质等)
    def get_numeric_input(prompt):
        while True:
            try:
                return int(input(f'{prompt}\n').strip())
            except ValueError:
                print('请输入有效的数字')
    
    foodCal = get_numeric_input('Enter calories')
    foodProtein = get_numeric_input('Enter protein')
    foodFat = get_numeric_input('Enter fat')
    foodCarbs = get_numeric_input('Enter carb')
    
    # 展示待保存信息
    print(f'''{foodName}
calorie: {foodCal}
protein: {foodProtein}
fat: {foodFat}
carbs: {foodCarbs}''')
    
    # 确认保存
    print('Confirm? Y/N')
    while True:
        confirmation = input().strip().upper()
        if confirmation in ('Y', 'N'):
            if confirmation == 'Y':
                conn = sqlite3.connect('food_tracker.db')
                cursor = conn.cursor()
                # 插入数据到数据库
                cursor.execute('''INSERT INTO foods 
                               (name, calories, protein, fat, carbs) 
                               VALUES (?, ?, ?, ?, ?)''',
                              (foodName.lower(), foodCal, foodProtein, foodFat, foodCarbs))
                conn.commit()
                conn.close()
                print('食物已保存')
            askOption()
            break

3. 添加便捷的删除函数

通过食物ID精准删除,避免纯文本的繁琐操作:

def deleteFood():
    conn = sqlite3.connect('food_tracker.db')
    cursor = conn.cursor()
    
    # 查询并展示所有食物
    cursor.execute('SELECT id, name FROM foods')
    foods = cursor.fetchall()
    if not foods:
        print('暂无食物记录')
        conn.close()
        askOption()
        return
    
    print('现有食物:')
    for food in foods:
        print(f'ID: {food[0]} - 名称: {food[1]}')
    
    # 获取并验证要删除的ID
    while True:
        try:
            food_id = int(input('请输入要删除的食物ID\n').strip())
            cursor.execute('SELECT * FROM foods WHERE id = ?', (food_id,))
            if not cursor.fetchone():
                print('该ID不存在,请重新输入')
                continue
            break
        except ValueError:
            print('请输入有效的数字ID')
    
    # 确认删除
    print(f'确定要删除ID为{food_id}的食物吗?Y/N')
    while True:
        confirmation = input().strip().upper()
        if confirmation in ('Y', 'N'):
            if confirmation == 'Y':
                cursor.execute('DELETE FROM foods WHERE id = ?', (food_id,))
                conn.commit()
                print('食物已删除')
            conn.close()
            askOption()
            break

方案二:优化JSON存储方式

如果不想用数据库,可将所有食物数据存储为JSON数组,每次操作时读取整个数组,修改后再写入文件,比零散的纯文本更易管理。

1. 封装JSON读写工具函数

import json
import os

FOOD_JSON_PATH = 'foods.json'

def load_foods():
    # 加载现有食物数据,文件不存在则返回空列表
    if not os.path.exists(FOOD_JSON_PATH):
        return []
    with open(FOOD_JSON_PATH, 'r', encoding='utf-8') as f:
        try:
            return json.load(f)
        except json.JSONDecodeError:
            return []

def save_foods(foods):
    # 将食物数据写入JSON文件
    with open(FOOD_JSON_PATH, 'w', encoding='utf-8') as f:
        json.dump(foods, f, indent=2, ensure_ascii=False)

2. 修改saveFood函数

def saveFood():
    foodName = input('Enter food name\n').strip().upper()
    
    def get_numeric_input(prompt):
        while True:
            try:
                return int(input(f'{prompt}\n').strip())
            except ValueError:
                print('请输入有效的数字')
    
    foodCal = get_numeric_input('Enter calories')
    foodProtein = get_numeric_input('Enter protein')
    foodFat = get_numeric_input('Enter fat')
    foodCarbs = get_numeric_input('Enter carb')
    
    # 展示待保存信息
    print(f'''{foodName}
calorie: {foodCal}
protein: {foodProtein}
fat: {foodFat}
carbs: {foodCarbs}''')
    
    print('Confirm? Y/N')
    while True:
        confirmation = input().strip().upper()
        if confirmation in ('Y', 'N'):
            if confirmation == 'Y':
                foods = load_foods()
                foods.append({
                    'name': foodName.lower(),
                    'calories': foodCal,
                    'protein': foodProtein,
                    'fat': foodFat,
                    'carbs': foodCarbs
                })
                save_foods(foods)
                print('食物已保存')
            askOption()
            break

3. 添加删除函数

def deleteFood():
    foods = load_foods()
    if not foods:
        print('暂无食物记录')
        askOption()
        return
    
    # 展示所有食物
    print('现有食物:')
    for idx, food in enumerate(foods, start=1):
        print(f'序号: {idx} - 名称: {food["name"]}')
    
    # 获取要删除的序号
    while True:
        try:
            delete_idx = int(input('请输入要删除的食物序号\n').strip()) - 1
            if delete_idx < 0 or delete_idx >= len(foods):
                print('序号无效,请重新输入')
                continue
            break
        except ValueError:
            print('请输入有效的数字序号')
    
    # 确认删除
    target_food = foods[delete_idx]
    print(f'确定要删除{target_food["name"]}吗?Y/N')
    while True:
        confirmation = input().strip().upper()
        if confirmation in ('Y', 'N'):
            if confirmation == 'Y':
                del foods[delete_idx]
                save_foods(foods)
                print('食物已删除')
            askOption()
            break

方案选择建议

  • 若你的应用数据量不大(个人日常使用),优化后的JSON方案足够简单易用;
  • 若需要支持复杂查询(比如按卡路里范围筛选)、数据量可能增长,SQLite方案更高效可靠。

内容的提问来源于stack exchange,提问作者SohrabFarjami

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 10:06:24