使用Peewee如何判断SQLite文件状态且避免自动创建表
问题与解决方案
现有SQLite文件检查逻辑
当前使用os.path实现的文件检查函数:
def check_db_exist(): try: file_exists = exists('games.db') if file_exists: file_size = os.path.getsize('games.db') if file_size > 3000: return True, file_size else: return False, 'too small' else: return False, 'does not exist' except: return False, 'error'
核心问题
- 导入模型时自动创建数据库文件:数据库模型文件中直接实例化
SqliteDatabase会自动生成空的games.db,导致文件存在性检查失去意义。模型代码如下:
db = SqliteDatabase('games.db') class Game(Model): game = CharField() exe = CharField() path = CharField() longpath = CharField() i_d = IntegerField() class Meta: database = db
- pywebview变量丢失:页面加载时会清空变量,无法直接获取文件检查的布尔值结果。
数据库操作函数现状
相关操作函数依赖全局db实例,注释掉模型中的db实例化会导致函数无法运行:
# db = SqliteDatabase('games.db') def add_game(game, exe, path, longpath, i_d): try: Game.create(game=game, exe=exe, path=path, longpath=longpath, i_d=i_d) except: pass def loop_insert(lib): db.connect() for i in lib[0]: add_game(i.name, i.exe, i.path, i.longpath, i.id) db.close() def initial_retrieve(): db.connect() vals = '' for games in Game.select(): val = js.Import.javascript(str(games.game), str(games.exe), str(games.path), games.i_d) vals = vals + val storage = vals db.close() return storage
解决方案
1. 延迟数据库初始化,避免导入时自动创建文件
修改模型文件,将数据库实例化与模型绑定延迟到确认文件存在后执行:
# models.py from peewee import SqliteDatabase, Model, CharField, IntegerField # 先定义空引用,不直接实例化 db = None class Game(Model): game = CharField() exe = CharField() path = CharField() longpath = CharField() i_d = IntegerField() class Meta: database = None # 暂不绑定数据库
添加数据库初始化函数,仅在需要时创建连接或表:
import os from os.path import exists, getsize def init_db(db_path='games.db'): global db db = SqliteDatabase(db_path) # 绑定数据库到Game模型 Game._meta.database = db # 仅当文件不存在或无效时,才创建表 if not exists(db_path) or getsize(db_path) <= 3000: db.connect() db.create_tables([Game]) db.close()
2. 调整流程顺序:先检查,后初始化
先执行文件检查,根据结果决定数据库初始化逻辑:
# 主流程 db_status, msg = check_db_exist() if db_status: # 数据库有效,仅初始化连接 init_db() else: # 数据库不存在或过小,初始化并创建表 init_db() # 可在此添加初始化数据的逻辑
3. 解决pywebview变量丢失问题
通过API桥接将检查结果暴露给前端,避免页面加载时变量丢失:
import webview # 先执行检查,保存结果 db_check_result = check_db_exist() def expose_to_frontend(): # 给前端提供获取检查结果的接口 return { 'getDbStatus': lambda: db_check_result } if __name__ == '__main__': webview.create_window('Game Library', 'index.html', js_api=expose_to_frontend()) webview.start()
前端可通过window.pywebview.api.getDbStatus()获取检查结果。
4. 修正数据库操作函数
确保操作函数依赖已初始化的db实例,并添加异常处理与连接关闭逻辑:
def add_game(game, exe, path, longpath, i_d): try: if db.is_closed(): db.connect() Game.create(game=game, exe=exe, path=path, longpath=longpath, i_d=i_d) except Exception as e: print(f"添加游戏失败: {str(e)}") finally: if not db.is_closed(): db.close() def loop_insert(lib): try: db.connect() for i in lib[0]: add_game(i.name, i.exe, i.path, i.longpath, i.id) except Exception as e: print(f"批量插入失败: {str(e)}") finally: if not db.is_closed(): db.close() def initial_retrieve(): vals = '' try: db.connect() for games in Game.select(): val = js.Import.javascript(str(games.game), str(games.exe), str(games.path), games.i_d) vals += val except Exception as e: print(f"查询数据失败: {str(e)}") finally: if not db.is_closed(): db.close() return vals
内容的提问来源于stack exchange,提问作者Sasha Alexander
相关产品推荐
相关产品推荐

