[ 问题解决 ] sqlite3.ProgrammingError: SQLite objects created in a thread can ...

目录

为什么会出现这个问题?

解决方法一:每个请求新建自己的连接(推荐)

[解决方法二:允许 SQLite 跨线程使用连接(不推荐)](#解决方法二:允许 SQLite 跨线程使用连接(不推荐))

小结


当你在 python 中使用 Flask 里面调用了数据库的操作的时候:

python 复制代码
def main():
    db = conn("DATABASE.db")
    Show(db)



def Show(db):
    app = Flask(__name__)

    @app.route('/')
    def demo():
        db.execute("Select * from ***")
        db.fetchall()

出现了如下 ERROR:

复制代码
sqlite3.ProgrammingError: SQLite objects created in a thread can only be used in that same thread.

这句话的意思是:

  • 你在 一个线程(比如 Flask 启动时的主线程)里创建了 SQLite 的连接或者 cursor(光标对象)。

  • 但你在 另一个线程(比如处理 POST 请求时 Flask 内部新开的线程)去用这个连接或者 cursor。

  • SQLite 默认不允许跨线程使用同一个连接

    SQLite 连接是线程绑定的,不同线程必须用自己的连接。


为什么会出现这个问题?

因为 Flask 默认是多线程运行的,每一个请求(特别是 POST 请求)都可能在不同线程中处理。如果你在 Flask 启动时创建了一个数据库连接并保存成了全局变量,然后在请求里用它,就会出错。


解决方法一:每个请求新建自己的连接(推荐)

最常见的方法是:

  • 每次请求都新建一个连接

  • 用完就关闭连接

可以在 Flask 里这样做:

python 复制代码
import sqlite3
from flask import Flask, g

app = Flask(__name__)

DATABASE = 'your_database.db'

def get_db():
    if 'db' not in g:
        g.db = sqlite3.connect(DATABASE)
    return g.db

@app.teardown_appcontext
def close_db(exception):
    db = g.pop('db', None)
    if db is not None:
        db.close()

@app.route('/your_route', methods=['POST'])
def your_post_handler():
    db = get_db()
    cursor = db.cursor()
    cursor.execute('YOUR SQL QUERY')
    result = cursor.fetchall()
    # process result...
    return 'Done'

解释一下:

  • g 是 Flask 提供的一个每个请求独立的小存储区,它跟线程绑定,安全。

  • get_db() 确保每个请求只打开一次数据库连接

  • @app.teardown_appcontext 这个函数确保请求结束时自动关闭连接

这样就不会有跨线程问题了。


解决方法二:允许 SQLite 跨线程使用连接(不推荐)

还有一种方法是:修改连接参数,允许 SQLite 跨线程用同一个连接:

python 复制代码
conn = sqlite3.connect(DATABASE, check_same_thread=False)

check_same_thread=False 表示允许在不同线程里使用同一个连接对象。

但是!!!

  • 这样做存在潜在的并发访问问题(比如两个线程同时读写,容易出错)。

  • SQLite 本身并不是高并发数据库,这样做虽然能避免报错,但隐藏了数据不一致或崩溃的风险

  • 一般只在自己清楚怎么管理线程安全时才敢这么用。

所以 不推荐新手用


小结

方案 特点 适用场景
每个请求新建连接 最安全,Flask推荐 正常开发
check_same_thread=False 有并发风险,需自己管理线程安全 小项目、测试用,不推荐

相关推荐
chase。1 分钟前
Python包构建工具完全指南:python -m build 使用详解
开发语言·chrome·python
ZhengEnCi3 分钟前
J7A-已有数据表如何安全添加新字段 🛡️
数据库
xin_yao_xin6 分钟前
PaddleOCR系列——《文本检测、文本识别》模型训练
人工智能·python·paddlepaddle·ppocr
2401_833197736 分钟前
用Python制作一个文字冒险游戏
jvm·数据库·python
一叶飘零_sweeeet12 分钟前
数据库连接池天花板之争:HikariCP 与 Druid 底层原理 + 高并发调优全拆解
数据库·hikaricp·数据库连接池·druid
GoodStudyAndDayDayUp13 分钟前
RUO-VUE-PRO权限关联sql
java·数据库·sql
@insist12314 分钟前
数据库系统工程师-SQL 数据定义语言(DDL)核心知识点与软考实战指南
数据库·oracle·软考·数据库系统工程师·软件水平考试
专利观察员15 分钟前
情报升维,决策降本:2026年专利数据库和专利检索实践的演进逻辑和实测
数据库
次旅行的库19 分钟前
【问渠哪得清如许-数据分析】学习笔记-下
数据库·笔记·sql·学习
万粉变现经纪人23 分钟前
如何解决 pip install cx_Oracle 报错 未找到 Oracle Instant Client 问题
数据库·python·mysql·oracle·pycharm·bug·pip