mirror of
https://github.com/open-webui/open-webui.git
synced 2026-07-17 08:21:12 -05:00
[PR #23710] [CLOSED] fix(db): patch SQLAlchemy ↔ aiosqlite ≥0.20 terminate_force_close incompatibility #130995
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
📋 Pull Request Information
Original PR: https://github.com/open-webui/open-webui/pull/23710
Author: @Classic298
Created: 4/14/2026
Status: ❌ Closed
Base:
dev← Head:claude/fix/aiosqlite-terminate-shim📝 Commits (3)
6bda95dfix(db): patch SQLAlchemy ↔ aiosqlite ≥0.20 terminate_force_close incompatibilitya03bde4fix(db): tighten aiosqlite terminate-shim install scope and worker wake-up4c45ab6fix(db): aiosqlite shim — bytecode fallback when source inspection fails📊 Changes
2 files changed (+211 additions, -0 deletions)
View changed files
➕
backend/open_webui/internal/_aiosqlite_compat.py(+198 -0)📝
backend/open_webui/internal/db.py(+13 -0)📄 Description
SQLAlchemy 2.0.36+ added a
terminate_force_close()path on its async DB-API adapters, used by the connection pool when a connection must be invalidated immediately (typically when an in-flight query was cancelled — request aborted by client, timeout, etc.).For the aiosqlite dialect,
_terminate_force_closeunconditionally accessesself._connection.stop. That attribute existed onaiosqlite.Connectionup to 0.18 (where Connection sub-classedthreading.Thread) and was removed in 0.20+ when the worker model was refactored.On the version pin Open WebUI ships (sqlalchemy 2.0.48 + aiosqlite 0.21.0) every cancelled aiosqlite call therefore produces a multi-page
NotImplementedError: terminate_force_close() not implemented by this DBAPI shim
ERROR traceback, drowning real errors in noise even though the underlying connection is correctly torn down by aiosqlite's own worker on the next loop tick.
Add
internal/_aiosqlite_compat.install()which monkey-patches the shim to understand both APIs:Connection.stop()as before._runningflag so it exits on the next iteration (the same end-state the original code achieved on the old API).The patch is idempotent, runs once at db.py import time before the async engine is created, and is a no-op on installations whose SQLAlchemy doesn't ship the affected symbol — so it won't break future upstream rewrites.
Contributor License Agreement
🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.