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

使用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'

核心问题

  1. 导入模型时自动创建数据库文件:数据库模型文件中直接实例化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
  1. 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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 04:35:54